【Socket】linux网络多路复用IO技术
生活随笔
收集整理的這篇文章主要介紹了
【Socket】linux网络多路复用IO技术
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.mystery引入
?
? ?1)Select是一種多路復用IO輸入輸出模式,在linux的輸入輸出編程中通過select的輪詢機制,發現可用/可讀或可寫的接口。? ?2)低級socket程序中有一個共同點:都是基于阻塞式的編程方式
? ?3)非阻塞式是函數調用時不阻塞,不管函數執行成功與否,都會立即返回。
? ?4)優點:程序效率提升
? ?5)缺點:返回的結果往往是錯誤的類型碼
? ?6)解決方案:Select機制。
2.實例操作
?
? ?1)基于Select模式實現一個網絡echo的服務程序,即客戶端向服務端發送信息,服務器接收到信息后,再將信息原樣轉發給客戶端? ?2)需要設置Select函數
? ?3)若當前有新連接,則加入到客戶端套接字集合,若數量過載,則斷開本次連接,并發送提示信息:sorry overload
? ?4)源代碼 //selectsocket.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define SERVER_PORT 5555 #define QUEUE_LENGTH 5 #define BUF_SIZE 200 int main(void) {int server_socket, new_socket;struct sockaddr_in server_addr; struct sockaddr_in client_addr;socklen_t sin_size;int client_socket[QUEUE_LENGTH]; int conn_num; int yes = 1;char buf[BUF_SIZE];int ret;int i;if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0){perror("socket");return 0;}if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){perror("setsockopt");return 0;}server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVER_PORT); server_addr.sin_addr.s_addr = INADDR_ANY;memset(server_addr.sin_zero, '\0', sizeof(server_addr.sin_zero));if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1){perror("bind");return 0;}if (listen(server_socket, 5) == -1){perror("listen");return 0;}printf("listen port %d\n", SERVER_PORT);fd_set clientfdset;int maxsock;struct timeval tv;conn_num = 0;sin_size = sizeof(client_addr);maxsock = server_socket;while (1){// initialize file descriptor setFD_ZERO(&clientfdset);FD_SET(server_socket, &clientfdset);// timeout settingtv.tv_sec = 15;tv.tv_usec = 0;// add active connection to fd setfor (i = 0; i < QUEUE_LENGTH; i++){if (client_socket[i] != 0){FD_SET(client_socket[i], &clientfdset);}}ret = select(maxsock + 1, &clientfdset, NULL, NULL, &tv);if (ret < 0){perror("select");break;}else if (ret == 0){printf("waitting timeout\n");continue;}// check every fd in the setfor (i = 0; i < conn_num; i++){if (FD_ISSET(client_socket[i], &clientfdset)){ret = recv(client_socket[i], buf, sizeof(buf), 0);if (ret <= 0){ printf("client[%d] close\n", i);close(client_socket[i]);FD_CLR(client_socket[i], &clientfdset);client_socket[i] = 0;}else{ printf("Client[%d] msg:%s\n", i, buf);send(client_socket[i], buf, sizeof(buf), 0);}}}if (FD_ISSET(server_socket, &clientfdset)){new_socket = accept(server_socket, (struct sockaddr *)&client_addr, &sin_size);if (new_socket <= 0){perror("accept");continue;}if (conn_num < QUEUE_LENGTH){client_socket[conn_num++] = new_socket;printf("new client[%d] %s:%d\n", conn_num,inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));if (new_socket > maxsock)maxsock = new_socket;}else{send(new_socket, "sorry overload!", sizeof("sorry overload!"), 0);close(new_socket);break;}}}for (i = 0; i < QUEUE_LENGTH; i++){if (client_socket[i] != 0){close(client_socket[i]);}} }
3.mystery注解
?
? ?1)設置高級socket屬性參數中的應用參數SO_REUSERADDR,實現地址的可重復利用? ?2)FD_SET(int fd, fd_set *fdset):向文件描述符集合中增加一個新的文件描述符
? ?3)FD_CLR(int fd, fd_set *fdset):向文件描述符集合中刪除一個文件描述符
?
轉載于:https://www.cnblogs.com/lcw/p/3159512.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的【Socket】linux网络多路复用IO技术的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: winform中关于panel中滚动条和
- 下一篇: sftp 服务器外网访问设置