使用select函数的TCP和UDP回射服务器程序
2013-11-03 19:22
232 查看
1,创建一个监听TCP套接字并捆绑服务器的总所周知端口, 设置SO_REUSEADDR套接字选项以防该端口上已有连接存在
2,还创建一个UDP套接字并捆绑与TCP套接字相同的端口,这里无需在调用bind之前设置SO_REUSEADDR套接字选项,因为TCP端口是独立于UDP端口的
3,我们调用select只是为了等待监听TCP套接字的可读条件或UDP套接字的可读条件。既然我们的sig_chld信号处理函数可能中断我们队select的调用,我们于是需要处理EINTR错误
udpservselect.c
2,还创建一个UDP套接字并捆绑与TCP套接字相同的端口,这里无需在调用bind之前设置SO_REUSEADDR套接字选项,因为TCP端口是独立于UDP端口的
3,我们调用select只是为了等待监听TCP套接字的可读条件或UDP套接字的可读条件。既然我们的sig_chld信号处理函数可能中断我们队select的调用,我们于是需要处理EINTR错误
udpservselect.c
#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <errno.h> #include <string.h> #include <sys/wait.h> #include <netinet/in.h> int main(int argc, char **argv) { int listenfd, connfd, udpfd, nready, maxfdp1; char mesg[MAXLINE]; pid_t clildpid; fd_set rset; ssize_t n; socklen_t len; const int on = 1; struct sockaddr_in cliaddr, servaddr; void sig_chld(int); listenfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htol(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); setsockopt(listenfd, SQL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); listen(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, (struct sockaddr *)&servaddr, sizeof(servaddr)); signal(SIGCHLD, sig_chld); FD_SET(&rset); maxfdp1 = max(listenfd, udpfd) + 1; for( ; ; ) { FD_SET(listenfd, &rset); FD_SET(udpfd, &rset); if((nready = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) { if(errno == EINTR) continue; else perror("select error"); } if(FD_ISSET(listenfd, &rset) { len = sizeof(cliaddr); connfd = accept(listenfd, (struct sockaddr *)&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, (struct sockaddr *)&cliaddr, &len); sendto(udpfd, mesg, n, 0, (struct sockaddr *)&cliaddr, &len); } } } void sig_chld(int signo) { pid_t pid; int stat; while((pid = waitpid(-1, &stat, WNOHANG)) > 0) printf("child %d terminated\n", pid); return; }
相关文章推荐
- 网络编程学习笔记(使用select函数的TCP和UDP回射服务器程序)
- UNIX网络编程——使用select函数的TCP和UDP回射服务器程序
- UNIX网络编程——使用select函数的TCP和UDP回射服务器程序
- UNIX网络编程——使用select函数的TCP和UDP回射服务器程序
- 使用select函数的TCP和UDP回射服务器程序
- select函数在TCP和UDP回射服务器中的应用
- DNS分别在什么情况下使用UDP和TCP?
- DNS使用TCP还是UDP?
- Socket通信——TCP、UDP区别总结、使用场景
- 游戏服务器:到底使用UDP还是TCP
- Java-Socket网络编程TCP和UDP的使用
- 关于使用UDP(TCP)跨局域网,NAT穿透的心得
- Android中使用TCP和UDP
- Nagios check_tcp和check_udp使用
- 关于使用UDP(TCP)跨局域网,NAT穿透
- 使用Nginx转发TCP/UDP数据
- linux网络编程之IP协议首部格式与其配套使用的四个协议(ARP,RARP,ICMP,IGMP)和TCP、UDP协议头结构总结
- PCATTCP使用笔记——TCP UDP速度测试工具
- Java 使用 TCP 和 UDP 传输文件
- 关于使用UDP(TCP)跨局域网,NAT穿透的心得