//passive.c 对tcp和udp通用 #include #include #include #include #include #include void error(int status, int err,char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); if(err) fprintf(stderr,":%s(%d)/n",strerror(err),err); if(status) exit(status); } static void set_address(const char * hname, const char *sname, struct sockaddr_in *sap, char *protocol) { struct servent *sp; struct hostent *hp; short port; bzero(sap, sizeof(*sap)); sap->sin_family = AF_INET; if(hname != NULL) { if(!inet_aton(hname, &sap->sin_addr)) { hp = gethostbyname(hname); if(hp == NULL) error(1, 0, "unkown host %s", hname); sap->sin_addr = *(struct in_addr *)hp->h_addr; } } else sap->sin_addr.s_addr = htonl(INADDR_ANY); if (sp = getservbyname(sname, protocol)) sap->sin_port = sp->s_port; else if ((sap->sin_port = htons((short)atoi(sname))) == 0) error(1,0,"unkown serivce %s", sname); } int server(char *hname, char *sname, char *protocol) { struct sockaddr_in local; int s,type; const int on = 1; if(strcmp(protocol,"tcp")==0) type = SOCK_STREAM; else type = SOCK_DGRAM; if((s=socket(AF_INET, type, 0)) <= 0) error(1, 0, "create socket failed!"); set_address(hname, sname, &local, protocol); if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) error(1,errno,"setsocket option failed!"); if(bind(s,(struct sockaddr *)&local,sizeof(local))) error(1, errno, "bind failed!"); if((type==SOCK_STREAM)&&listen(s,5)) error(1, errno, "listen error!"); return s; } //tcpserver.c 子进程 #include #include #include #include #include #include #include #include #include void process_server(int s, struct sockaddr_in * remote) { int len; time_t ti; char buff[128]; printf("connection from: %s:%d/n",inet_ntoa(remote->sin_addr),ntohs(remote->sin_port)); ti=time(NULL); //snprintf(buff,sizeof(buff),"%s/r/n",ctime(&ti)); while((len=recv(s,buff,sizeof(buff),0))>0) { buff[len]='/0'; send(s, buff,strlen(buff), 0); bzero(buff,sizeof(buff)); } } void sig_child() { pid_t pid; int status; while((pid=waitpid(-1,&status,WNOHANG))>0) printf("%d terminated!/n",pid); // while(wait(&status)>0); } int main(int argc, char **argv) { struct sockaddr_in remote; char *hname, *sname; int s, c, len; pid_t pid; if(argc < 2) error(1,0,"parameters less than 2"); else if(argc == 2) { hname = NULL; sname = argv[1]; } else if(argc == 3) { hname = argv[1]; sname = argv[2]; } s = server(hname, sname,"tcp"); signal(SIGCHLD,sig_child); len = sizeof(struct sockaddr); while(1) { if((c=accept(s,(struct sockaddr *)&remote,&len))<=0){ if(errno == EINTR) continue; error(1,errno,"accept error!"); } if((pid=fork())>0) { close(c); continue; } else if(pid < 0) err(1,0,"fork error!"); close(s); process_server(c,&remote); exit(0); } close(s); exit(0); } //tcpserver.c 用select #include #include #include #include #include #include #include #include #include #include void sig_child() { pid_t pid; int status; while((pid=waitpid(-1,&status,WNOHANG))>0) printf("%d terminated!/n",pid); // while(wait(&status)>0); } int main(int argc, char **argv) { struct sockaddr_in remote; char *hname, *sname; int s, c, len,fd; pid_t pid; fd_set rset,allset; int client[1024]; int i,maxi,maxfd,nready; char buff[1024]; if(argc < 2) error(1,0,"parameters less than 2"); else if(argc == 2) { hname = NULL; sname = argv[1]; } else if(argc == 3) { hname = argv[1]; sname = argv[2]; } s = server(hname, sname,"tcp"); signal(SIGCHLD,sig_child); len = sizeof(struct sockaddr); FD_ZERO(&allset); FD_ZERO(&rset); FD_SET(s,&allset); maxi=0; maxfd=s; for(i=0;i<1024;i++) client[i]=-1; while(1) { rset=allset; if((nready=select(maxfd+1,&rset,NULL,NULL,NULL))<0) error(1,0,"select error!!"); if(FD_ISSET(s,&rset)) { if((c=accept(s,(struct sockaddr *)&remote,&len))<=0){ error(1,errno,"accept error!"); } for(i=0; i<1024; i++) { if(client[i] != -1) continue; else { client[i]= c; break; } } if(i == 1024) error(1,0,"too many clients!!"); FD_SET(c,&allset); if(c>maxfd) maxfd = c; if(i > maxi) maxi = i; if(--nready==0) continue; } for(i=0;i<= maxi;i++){ if((fd=client[i])==-1) continue; if(FD_ISSET(fd,&rset)){ if((len=recv(fd,buff,sizeof(buff),0))>0) { buff[len]='/0'; send(fd, buff,strlen(buff), 0); bzero(buff,sizeof(buff)); } else { close(fd); FD_CLR(fd,&allset); client[i]=-1; } if(--nready==0) break; } } } close(s); exit(0); } //udpserver..c #include #include #include #include #include #include void process_server(int s) { struct sockaddr_in remote; char buff[128]; int len,n; while(1){ n=recvfrom(s,buff,sizeof(buff),0,(struct sockaddr *)&remote,&len); //printf("%s,%d/n",buff,n); buff[n]='/0'; sendto(s,buff,strlen(buff), 0, (struct sockaddr *)&remote,sizeof(remote)); } } int main(int argc, char **argv) { struct sockaddr_in remote; char *hname, *sname; int s, c, len; if(argc < 2) error(1,0,"parameters less than 2"); else if(argc == 2) { hname = NULL; sname = argv[1]; } else if(argc == 3) { hname = argv[1]; sname = argv[2]; } s = server(hname, sname,"udp"); process_server(s); close(s); exit(0); }