日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

socekt编程-select

發布時間:2023/11/30 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 socekt编程-select 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

摘抄自
https://blog.csdn.net/lovekun1989/article/details/41042273
https://blog.csdn.net/Ctrl_qun/article/details/52524086
分為無select和有select版本,無select只能一個服務端一個客戶端,有select能一個服務端對應多個客戶端。
無select,服務端代碼

/*socket tcp服務器端*/ #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h>#define SERVER_PORT 5555/*監聽后,一直處于accept阻塞狀態,直到有客戶端連接,當客戶端如數quit后,斷開與客戶端的連接*/int main() {//調用socket函數返回的文件描述符int serverSocket;//聲明兩個套接字sockaddr_in結構體變量,分別表示客戶端和服務器struct sockaddr_in server_addr;struct sockaddr_in clientAddr;int addr_len = sizeof(clientAddr);int client;char buffer[200];int iDataNum;//socket函數,失敗返回-1//int socket(int domain, int type, int protocol);//第一個參數表示使用的地址類型,一般都是ipv4,AF_INET//第二個參數表示套接字類型:tcp:面向連接的穩定數據傳輸SOCK_STREAM//第三個參數設置為0if((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0){perror("socket");return 1;}bzero(&server_addr, sizeof(server_addr));//初始化服務器端的套接字,并用htons和htonl將端口和地址轉成網絡字節序server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);//ip可是是本服務器的ip,也可以用宏INADDR_ANY代替,代表0.0.0.0,表明所有地址server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//對于bind,accept之類的函數,里面套接字參數都是需要強制轉換成(struct sockaddr *)//bind三個參數:服務器端的套接字的文件描述符,if(bind(serverSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){perror("connect");return 1;}//設置服務器上的socket為監聽狀態if(listen(serverSocket, 5) < 0) {perror("listen");return 1;}while(1){printf("Listening on port: %d\n", SERVER_PORT);//調用accept函數后,會進入阻塞狀態//accept返回一個套接字的文件描述符,這樣服務器端便有兩個套接字的文件描述符,//serverSocket和client。//serverSocket仍然繼續在監聽狀態,client則負責接收和發送數據//clientAddr是一個傳出參數,accept返回時,傳出客戶端的地址和端口號//addr_len是一個傳入-傳出參數,傳入的是調用者提供的緩沖區的clientAddr的長度,以避免緩沖區溢出。//傳出的是客戶端地址結構體的實際長度。//出錯返回-1client = accept(serverSocket, (struct sockaddr*)&clientAddr, (socklen_t*)&addr_len);if(client < 0){perror("accept");continue;}printf("\nrecv client data...n");//inet_ntoa ip地址轉換函數,將網絡字節序IP轉換為點分十進制IP//表達式:char *inet_ntoa (struct in_addr);printf("IP is %s\n", inet_ntoa(clientAddr.sin_addr));printf("Port is %d\n", htons(clientAddr.sin_port));while(1){iDataNum = recv(client, buffer, 1024, 0);if(iDataNum < 0){perror("recv");continue;}buffer[iDataNum] = '\0';if(strcmp(buffer, "quit") == 0)break;printf("%drecv data is %s\n", iDataNum, buffer);send(client, buffer, iDataNum, 0);}}return 0; }

無select,客戶端代碼

/*socket tcp客戶端*/ #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h>#define SERVER_PORT 5555/*連接到服務器后,會不停循環,等待輸入,輸入quit后,斷開與服務器的連接*/int main() {//客戶端只需要一個套接字文件描述符,用于和服務器通信int clientSocket;//描述服務器的socketstruct sockaddr_in serverAddr;char sendbuf[200];char recvbuf[200];int iDataNum;if((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0){perror("socket");return 1;}serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(SERVER_PORT);//指定服務器端的ip,本地測試:127.0.0.1//inet_addr()函數,將點分十進制IP轉換成網絡字節序IPserverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");if(connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0){perror("connect");return 1;}printf("connect with destination host...\n");while(1){printf("Input your world:>");scanf("%s", sendbuf);printf("\n");send(clientSocket, sendbuf, strlen(sendbuf), 0);if(strcmp(sendbuf, "quit") == 0)break;iDataNum = recv(clientSocket, recvbuf, 200, 0);recvbuf[iDataNum] = '\0';printf("recv data of my world is: %s\n", recvbuf);}close(clientSocket);return 0; }

有select,服務端代碼

/*socket tcp服務器端*/ #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h>#define SERVER_PORT 5555 #define CLIENT_MAX 5 #define BUFFER_SIZE 200int main() {int serverSocket;struct sockaddr_in server_addr;struct sockaddr_in clientAddr;int addr_len = sizeof(clientAddr);int client, i, ret;char buffer[BUFFER_SIZE];char in_msg[BUFFER_SIZE];char recv_msg[BUFFER_SIZE];int iDataNum;int client_fds[CLIENT_MAX];fd_set server_fd_set;int max_fd = -1;struct timeval tv;if((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0){perror("socket");return 1;}bzero(&server_addr, sizeof(server_addr));//初始化服務器端的套接字,并用htons和htonl將端口和地址轉成網絡字節序server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);//ip可是是本服務器的ip,也可以用宏INADDR_ANY代替,代表0.0.0.0,表明所有地址server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//對于bind,accept之類的函數,里面套接字參數都是需要強制轉換成(struct sockaddr *)//bind三個參數:服務器端的套接字的文件描述符,if(bind(serverSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {perror("connect");return 1;}if(listen(serverSocket, 5) < 0) {perror("listen");return 1;}while(1) {tv.tv_sec = 20;tv.tv_usec = 0;FD_ZERO(&server_fd_set);FD_SET(STDIN_FILENO, &server_fd_set);if (max_fd < STDIN_FILENO) {max_fd = STDIN_FILENO;}FD_SET(serverSocket, &server_fd_set);if (max_fd < serverSocket) {max_fd = serverSocket;}for (i = 0; i < CLIENT_MAX; i++) {if (client_fds[i] != 0) {FD_SET(client_fds[i], &server_fd_set);if (max_fd < client_fds[i]) {max_fd = client_fds[i];}}}ret = select(max_fd + 1, &server_fd_set, NULL, NULL, &tv);if (ret < 0) {perror("select error");continue;} else if (ret == 0) {printf("wait ...\n");continue;} else {if (FD_ISSET(STDIN_FILENO, &server_fd_set)) {printf("send msg:");memset(in_msg, 0, BUFFER_SIZE);fgets(in_msg, BUFFER_SIZE, stdin);if (strcmp(in_msg, "quit") == 0) {exit(0);}for (i = 0; i < CLIENT_MAX; i++) {if (client_fds[i] != 0) {printf("send msg to [i:%d] [fd:%d]..\n", i, client_fds[i]);send(client_fds[i], in_msg, BUFFER_SIZE, 0);}}}if (FD_ISSET(serverSocket, &server_fd_set)) {client = accept(serverSocket, (struct sockaddr*)&clientAddr, (socklen_t*)&addr_len);if(client > 0) {int index =-1;for (i = 0; i < CLIENT_MAX; i++) {if (client_fds[i] == 0) {client_fds[i] = client;index = i;break;}}if (index >= 0) {printf("add client [%d] success, %s:%d.\n", index, inet_ntoa(clientAddr.sin_addr),htons(clientAddr.sin_port));} else {memset(in_msg, 0, BUFFER_SIZE);strcpy(in_msg, "add client fail, reach max client.\n");send(client, in_msg, BUFFER_SIZE, 0);printf("add client fail, reach max client.\n");}}}for (i = 0; i < CLIENT_MAX; i++) {if (client_fds[i] !=0 ) {if (FD_ISSET(client_fds[i], &server_fd_set)) {memset(recv_msg, 0, BUFFER_SIZE);iDataNum = recv(client_fds[i], recv_msg, BUFFER_SIZE, 0);if (iDataNum < 0) {perror("recv");continue;} else if (iDataNum > 0) {if (iDataNum > BUFFER_SIZE) {iDataNum = BUFFER_SIZE;}recv_msg[iDataNum] = '\0';printf("recv %d msg:%s.\n", client_fds[i], recv_msg);} else {FD_CLR(client_fds[i], &server_fd_set);client_fds[i] = 0; printf("client (%d) exit.\n", i);}}}}}}return 0; }

有select,客戶端代碼

/*socket tcp客戶端*/ #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h>#define SERVER_PORT 5555/*連接到服務器后,會不停循環,等待輸入,輸入quit后,斷開與服務器的連接*/int main() {//客戶端只需要一個套接字文件描述符,用于和服務器通信int clientSocket;//描述服務器的socketstruct sockaddr_in serverAddr;char sendbuf[200];char recvbuf[200];int iDataNum;fd_set client_fd_set;struct timeval tv;int ret;if((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0){perror("socket");return 1;}serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(SERVER_PORT);//指定服務器端的ip,本地測試:127.0.0.1//inet_addr()函數,將點分十進制IP轉換成網絡字節序IPserverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");if(connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0){perror("connect");return 1;}printf("connect with destination host...\n");while(1){tv.tv_sec = 20;tv.tv_usec = 0;FD_ZERO(&client_fd_set); FD_SET(STDIN_FILENO, &client_fd_set);FD_SET(clientSocket, &client_fd_set);ret = select(clientSocket + 1, &client_fd_set, NULL, NULL, &tv);if (ret < 0) {perror("select error");continue;} else if (ret == 0) {//超時continue;} if(FD_ISSET(STDIN_FILENO, &client_fd_set)) {memset(sendbuf, 0, 200);scanf("%s", sendbuf);send(clientSocket, sendbuf, strlen(sendbuf), 0);printf("send msg: %s\n");if(strcmp(sendbuf, "quit") == 0) {break;}}if(FD_ISSET(clientSocket, &client_fd_set)) {memset(recvbuf, 0, 200);iDataNum = recv(clientSocket, recvbuf, 200, 0);if (iDataNum > 0) {recvbuf[iDataNum] = '\0';printf("recv data of my world is: %s", recvbuf);} else if(iDataNum < 0) {printf("接受消息出錯!\n");} else {printf("服務器端退出!\n");exit(0); }}}close(clientSocket);return 0; }

總結

以上是生活随笔為你收集整理的socekt编程-select的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。