生活随笔
收集整理的這篇文章主要介紹了
Linux网络编程——tcp并发服务器(I/O复用之select)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
https://blog.csdn.net/lianghe_work/article/details/46519633
與多線程、多進程相比,I/O復用最大的優勢是系統開銷小,系統不需要建立新的進程或者線程,也不必維護這些線程和進程。
代碼示例:
#include <stdio.h> #include <unistd.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/socket.h>#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/select.h> #define SERV_PORT 8080#define LIST 20 //服務器最大接受連接#define MAX_FD 10 //FD_SET支持描述符數量 int main(int argc, char *argv[]){ int sockfd; int err; int i; int connfd; int fd_all[MAX_FD]; fd_set fd_read; fd_set fd_select; struct timeval timeout; struct timeval timeout_select; struct sockaddr_in serv_addr; struct sockaddr_in cli_addr; socklen_t serv_len;socklen_t cli_len; timeout.tv_sec = 10;timeout.tv_usec = 0; sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd < 0){perror("fail to socket");exit(1);} memset(&serv_addr, 0, sizeof(serv_addr));serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(SERV_PORT); serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_len = sizeof(serv_addr); err = bind(sockfd, (struct sockaddr *)&serv_addr, serv_len); if(err < 0){perror("fail to bind");exit(1);} err = listen(sockfd, LIST); if(err < 0){perror("fail to listen");exit(1);} memset(fd_all, -1, sizeof(fd_all)); fd_all[0] = sockfd; FD_ZERO(&fd_read); FD_SET(sockfd, &fd_read); int maxfd = fd_all[0]; while(1){ fd_select = fd_read;timeout_select = timeout; err = select(maxfd+1, &fd_select, NULL, NULL, NULL); if(err < 0){perror("fail to select");exit(1);} if(err == 0){printf("timeout\n");} if( FD_ISSET(sockfd, &fd_select) ){ cli_len = sizeof(cli_addr); connfd = accept(sockfd, (struct sockaddr *)&cli_addr, &cli_len); if(connfd < 0){perror("fail to accept");exit(1);} char cli_ip[INET_ADDRSTRLEN] = {0};inet_ntop(AF_INET, &cli_addr.sin_addr, cli_ip, INET_ADDRSTRLEN);printf("----------------------------------------------\n");printf("client ip=%s,port=%d\n", cli_ip,ntohs(cli_addr.sin_port)); for(i=0; i < MAX_FD; i++){ if(fd_all[i] != -1){ continue;}else{fd_all[i] = connfd;printf("client fd_all[%d] join\n", i); break;}} FD_SET(connfd, &fd_read); if(maxfd < connfd){maxfd = connfd; } } for(i=1; i < maxfd; i++){ if(FD_ISSET(fd_all[i], &fd_select)){printf("fd_all[%d] is ok\n", i); char buf[1024]={0}; int num = read(fd_all[i], buf, 1024); if(num > 0){ printf("receive buf from client fd_all[%d] is: %s\n", i, buf); num = write(fd_all[i], buf, num); if(num < 0){perror("fail to write ");exit(1);}else{ } } else if(0 == num){ printf("client:fd_all[%d] exit\n", i);FD_CLR(fd_all[i], &fd_read);close(fd_all[i]);fd_all[i] = -1; continue;} }else { }}} return 0;}運行結果:
總結
以上是生活随笔為你收集整理的Linux网络编程——tcp并发服务器(I/O复用之select)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。