int ld,sd,udp;
struct sockaddr_in skaddr
int length;
fd_set fd;
int max;
int n;
char buff[1000];
/*-----------------tcp---------------*/
if ((ld = socket( PF_INET, SOCK_STREAM, 0 )) < 0) {
perror("Problem creating socket\n");
exit(1);
}
skaddr.sin_family = AF_INET;
skaddr.sin_addr.s_addr = htonl(INADDR_ANY);
skaddr.sin_port = htons(atoi(argv[1]));
if (bind(ld, (struct sockaddr *) &skaddr, sizeof(skaddr))<0) {
perror("Problem binding\n");
exit(0);
}
if (listen(ld,5) < 0 ) {
perror("Error calling listen\n");
exit(1);
}
/*---------------------udp-----------------*/
if ((udp = socket( PF_INET, SOCK_DGRAM, 0 )) < 0) {
printf("Problem creating socket\n"); exit(1);
}
if (bind(udp, (struct sockaddr *) &skaddr, sizeof(skaddr))<0) {
printf("Problem binding\n");
exit(0);
}
max = (ld > udp ? ld : udp);
while (1) {
/* Inialize the fd_set */
FD_ZERO(&fd);
FD_SET(ld,&fd); /* add passive tcp socket */
FD_SET(udp,&fd); /* add udp socket */
/*--------------select--------------*/
/* call select */
if (select(max+1,&fd,NULL,NULL,NULL)<0) {
perror("select problem");
exit(1);
}
/*判断如果是tcp的socket执行那些操作*/
if (FD_ISSET(ld,&fd) ) {
if ((sd = accept(ld, (struct sockaddr *) &skaddr, &length))<0) {
perror("accept problem");
exit(1);
}
while (n = read(sd,buff,1000)) {
if (write(sd,buff,n)<0)
break;
}
close(sd);
}
/*判断如果是udp的socket执行那些操作*/
if (FD_ISSET(udp,&fd)) {
/* read a datagram from the socket (put result in bufin) */
n=recvfrom(udp,buff,1000,0,(struct sockaddr *)&skaddr,&length);
if (n<0) {
perror("Error receiving data");
} else {
/* Got something, just send it back */
sendto(udp,buff,n,0,(struct sockaddr *)&skaddr,length);
}
}
}
}
We
want a process that can operate as both a TCP echo server and a UDP
echo server. The process can provide service to many clients at the same
time, but involves a single process that does not start up any other
threads.
其实程序并没有想象中的复杂。既然一个server 要同时支持两个协议的socket.我们需要知道他们彼此的区别:
基于连接与无连接
对系统资源的要求(TCP较多,UDP少)
UDP程序结构较简单
流模式与数据报模式
具体编程时的区别
1. socket()的参数不同
2. UDP Server不需要调用listen和accept
3. UDP收发数据用sendto/recvfrom函数
4. TCP:地址信息在connect/accept时确定
UDP:在sendto/recvfrom函数中每次均 需指定地址信息
5. UDP:shutdown函数无效
程
序中我们也可以看出用到了select函数来判断当前的连接是udp
还是tcp的,根据不同的协议,虽然都是展现echo功能,但是方法却不一样,udp用的是receform以及sendto两个函数,而tcp用的是
accept以及rea/write函数来实现的。