首先 运行在linux 运行gcc -g -o select select.c
/ *******select.c*********/ / *******Using select() for I/O multiplexing */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> /* port we're listening on */ #define PORT 2020 int main(int argc, char *argv[]) { /*定义描述符集合 */ fd_set master; /* 定义select函数可读的描述符*/ fd_set read_fds; /* 服务器地址 */ struct sockaddr_in serveraddr; /* 客户地址 */ struct sockaddr_in clientaddr; /* 定义最大描述符数 */ int fdmax; /* 监听描述符 */ int listener; /* accept描述符 */ int newfd; /* 缓冲 */ char buf[1024]; int nbytes; /* 设置 setsockopt() SO_REUSEADDR */ int yes = 1; int addrlen; int i, j; /* 清除 */ FD_ZERO(&master); FD_ZERO(&read_fds); /* 连接 */ if((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Server-socket() error lol!"); exit(1); } printf("Server-socket() is OK...\n"); /*判断地址以用 */ if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("Server-setsockopt() error lol!"); exit(1); } printf("Server-setsockopt() is OK...\n"); /* bind */ serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = INADDR_ANY; serveraddr.sin_port = htons(PORT); memset(&(serveraddr.sin_zero), '\0', 8); if(bind(listener, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1) { perror("Server-bind() error lol!"); exit(1); } printf("Server-bind() is OK...\n"); /* listen */ if(listen(listener, 10) == -1) { perror("Server-listen() error lol!"); exit(1); } printf("Server-listen() is OK...\n"); /* 把 listener 加到 master set */ FD_SET(listener, &master); /* keep track of the biggest file descriptor */ fdmax = listener; /* so far, it's this one*/ /* 循环了 */ for(;;) { /* copy it */ read_fds = master; if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { perror("Server-select() error lol!"); exit(1); } printf("Server-select() is OK...\n"); /*从存在的描述符中查找要读的数据*/ for(i = 0; i <= fdmax; i++) { if(FD_ISSET(i, &read_fds)) { /* 得到一个... */ if(i == listener) { /* h处理这个的连接 */ addrlen = sizeof(clientaddr); if((newfd = accept(listener, (struct sockaddr *)&clientaddr, &addrlen)) == -1) { perror("Server-accept() error lol!"); } else { printf("Server-accept() is OK...\n"); FD_SET(newfd, &master); /* add to master set */ if(newfd > fdmax) { /* keep track of the maximum */ fdmax = newfd; } printf("%s: New connection from %s on socket %d\n", argv[0], inet_ntoa(clientaddr.sin_addr), newfd); } } else { /* 处理从客户端来的数据*/ if((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) { /* 没有数据 */ if(nbytes == 0) /* 断开连接。 */ printf("%s: socket %d hung up\n", argv[0], i); else perror("recv() error lol!"); /* 关闭... */ close(i); /* 删除这个连接符 */ FD_CLR(i, &master); } else { /* we got some data from a client*/ for(j = 0; j <= fdmax; j++) { /* 发给每个人! */ if(FD_ISSET(j, &master)) { /* 除了监听的和自己的。 */ if(j != listener && j != i) { if(send(j, buf, nbytes, 0) == -1) perror("send() error lol!"); } } } } } } } } return 0; }
然后在运行 ./select & 或者ctrl+z 让他后台运行
开一个窗口 运行telnet localhostip 2020
程序如下
更多文章,欢迎访问http://blog.youkuaiyun.com/wallwind 转载请注明出处
unix网络编程之利用select 实现群发的功能
最新推荐文章于 2025-04-26 16:43:32 发布