使用select函数的TCP和UDP回射服务器程序
#include "unp.h"
int main(int argc, char **argv){
int listenfd, connfd, udpfd, nready, maxfdp1;
char mesg[MAXLINE];
pid_t childpid;
fd_set rset;
ssize_t n;
socklen_t len;
const int on = 1;
struct sockaddr_in cliaddr, servaddr;
void sig_chld(int); //创建TCP的监听
listenfd = socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
setsockopt(listenfd,SOL_SOCKET,SO_REUSERADDR,&on,sizeof(on));
bind(listenfd, LISTENQ);
udpfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind(udpfd, (SA*) &servaddr, sizeof(servaddr));
signal(SIGCHLD, sig_chld);
FD_ZERO(&rset);
maxfdpl = max(listenfd,udpfd)+1;
for(;;){
FD_SET(listenfd,&rset);
FD_SET(udpfd,&rset);
if((nready = select(maxfdpl, &rset, NULL, NULL, NULL)) < 0){
if(errno == EINTR)
continue;
else
err_sys("select error");
}
if(FD_ISSET(listenfd, &rset)){
len = sizeof(cliaddr);
connfd = accept(listenfd,(SA *) &cliaddr, &len);
if((childpid = fork()) == 0){ //子进程
close(listenfd); //关闭监听套接字
str_echo(connfd); //处理请求
exit(0);
}
close(connfd); //关闭父连接套接字
}
if(FD_ISSET(udpfd, &rset)){
len = sizeof(cliaddr);
n = recvfrom(udpfd, mesg, MAXLINE, 0, (SA*) &cliaddr, &len);
sendto(udpfd,mesg, n, 0, (SA*) &cliaddr, 0);
}
}
}