AI智能
改变未来

(TCP IP网络编程)实验五 I/O复用模型编程


一.实验目的

(1) 理解I/O复用模型的工作原理;
(2) 掌握select函数的功能和调用顺序;
(3) 掌握I/O复用模型服务器编程。

二.实验内容

(1) 在Linux下实现一个以I/O复用模型为基础的回声服务器端(及客户端);
(2) 在Windows下实现一个以I/O复用模型为基础的回声服务器端(及客户端)。

三.实验过程

(1)实验代码:

echo_selectserv.c:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/select.h>#define BUF_SIZE 100void error_handling(char *buf);int main(int argc, char *argv[]){int serv_sock, clnt_sock;struct sockaddr_in serv_adr, clnt_adr;struct timeval timeout;fd_set reads, cpy_reads;socklen_t adr_sz;int fd_max, str_len, fd_num, i;char buf[BUF_SIZE];if(argc!=2) {printf(\"Usage : %s <port>\\n\", argv[0]);exit(1);}serv_sock=socket(PF_INET, SOCK_STREAM, 0);memset(&serv_adr, 0, sizeof(serv_adr));serv_adr.sin_family=AF_INET;serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);serv_adr.sin_port=htons(atoi(argv[1]));if(bind(serv_sock, (struct sockaddr*) &serv_adr, sizeof(serv_adr))==-1)error_handling(\"bind() error\");if(listen(serv_sock, 5)==-1)error_handling(\"listen() error\");FD_ZERO(&reads);FD_SET(serv_sock, &reads);fd_max=serv_sock;while(1){cpy_reads=reads;timeout.tv_sec=5;timeout.tv_usec=5000;if((fd_num=select(fd_max+1, &cpy_reads, 0, 0, &timeout))==-1)break;if(fd_num==0)continue;for(i=0; i<fd_max+1; i++){if(FD_ISSET(i, &cpy_reads)){if(i==serv_sock)     // connection request!{adr_sz=sizeof(clnt_adr);clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_adr, &adr_sz);FD_SET(clnt_sock, &reads);if(fd_max<clnt_sock)fd_max=clnt_sock;printf(\"connected client: %d \\n\", clnt_sock);}else    // read message!{str_len=read(i, buf, BUF_SIZE);if(str_len==0)    // close request!{FD_CLR(i, &reads);close(i);printf(\"closed client: %d \\n\", i);}else{write(i, buf, str_len);    // echo!}}}}}close(serv_sock);return 0;}void error_handling(char *buf){fputs(buf, stderr);fputc(\'\\n\', stderr);exit(1);}echo_client.c:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <sys/socket.h>#define BUF_SIZE 1024void error_handling(char *message);int main(int argc, char *argv[]){int sock;char message[BUF_SIZE];int str_len;struct sockaddr_in serv_adr;if(argc!=3) {printf(\"Usage : %s <IP> <port>\\n\", argv[0]);exit(1);}sock=socket(PF_INET, SOCK_STREAM, 0);if(sock==-1)error_handling(\"socket() error\");memset(&serv_adr, 0, sizeof(serv_adr));serv_adr.sin_family=AF_INET;serv_adr.sin_addr.s_addr=inet_addr(argv[1]);serv_adr.sin_port=htons(atoi(argv[2]));if(connect(sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr))==-1)error_handling(\"connect() error!\");elseputs(\"Connected...........\");while(1){fputs(\"Input message(Q to quit): \", stdout);fgets(message, BUF_SIZE, stdin);if(!strcmp(message,\"q\\n\") || !strcmp(message,\"Q\\n\"))break;write(sock, message, strlen(message));str_len=read(sock, message, BUF_SIZE-1);message[str_len]=0;printf(\"Message from server: %s\", message);}close(sock);return 0;}void error_handling(char *message){fputs(message, stderr);fputc(\'\\n\', stderr);exit(1);}

结果:

(2)实验代码:

echo_selectserv_win.c:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <winsock2.h>#define BUF_SIZE 1024void ErrorHandling(char* message);int main(int argc, char* argv[]){WSADATA wsaData;SOCKET hServSock, hClntSock;SOCKADDR_IN servAdr, clntAdr;TIMEVAL timeout;fd_set reads, cpyReads;int adrSz;int strLen, fdNum, i;char buf[BUF_SIZE];if (argc != 2) {printf(\"Usage : %s <port>\\n\", argv[0]);exit(1);}if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)ErrorHandling(\"WSAStartup() error!\");hServSock = socket(PF_INET, SOCK_STREAM, 0);memset(&servAdr, 0, sizeof(servAdr));servAdr.sin_family = AF_INET;servAdr.sin_addr.s_addr = htonl(INADDR_ANY);servAdr.sin_port = htons(atoi(argv[1]));if (bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)ErrorHandling(\"bind() error\");if (listen(hServSock, 5) == SOCKET_ERROR)ErrorHandling(\"listen() error\");FD_ZERO(&reads);FD_SET(hServSock, &reads);while (1){cpyReads = reads;timeout.tv_sec = 5;timeout.tv_usec = 5000;if ((fdNum = select(0, &cpyReads, 0, 0, &timeout)) == SOCKET_ERROR)break;if (fdNum == 0)continue;for (i = 0; i < reads.fd_count; i++){if (FD_ISSET(reads.fd_array[i], &cpyReads)){if (reads.fd_array[i] == hServSock)     // connection request!{adrSz = sizeof(clntAdr);hClntSock =accept(hServSock, (SOCKADDR*)&clntAdr, &adrSz);FD_SET(hClntSock, &reads);printf(\"connected client: %d \\n\", hClntSock);}else    // read message!{strLen = recv(reads.fd_array[i], buf, BUF_SIZE - 1, 0);if (strLen == 0)    // close request!{FD_CLR(reads.fd_array[i], &reads);closesocket(cpyReads.fd_array[i]);printf(\"closed client: %d \\n\", cpyReads.fd_array[i]);}else{send(reads.fd_array[i], buf, strLen, 0);    // echo!}}}}}closesocket(hServSock);WSACleanup();return 0;}void ErrorHandling(char* message){fputs(message, stderr);fputc(\'\\n\', stderr);exit(1);}echo_client_win.c:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <winsock2.h>#define BUF_SIZE 1024void ErrorHandling(char* message);int main(int argc, char* argv[]){WSADATA wsaData;SOCKET hSocket;char message[BUF_SIZE];int strLen;SOCKADDR_IN servAdr;if (argc != 3) {printf(\"Usage : %s <IP> <port>\\n\", argv[0]);exit(1);}if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)ErrorHandling(\"WSAStartup() error!\");hSocket = socket(PF_INET, SOCK_STREAM, 0);if (hSocket == INVALID_SOCKET)ErrorHandling(\"socket() error\");memset(&servAdr, 0, sizeof(servAdr));servAdr.sin_family = AF_INET;servAdr.sin_addr.s_addr = inet_addr(argv[1]);servAdr.sin_port = htons(atoi(argv[2]));if (connect(hSocket, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)ErrorHandling(\"connect() error!\");elseputs(\"Connected...........\");while (1){fputs(\"Input message(Q to quit): \", stdout);fgets(message, BUF_SIZE, stdin);if (!strcmp(message, \"q\\n\") || !strcmp(message, \"Q\\n\"))break;send(hSocket, message, strlen(message), 0);strLen = recv(hSocket, message, BUF_SIZE - 1, 0);message[strLen] = 0;printf(\"Message from server: %s\", message);}closesocket(hSocket);WSACleanup();return 0;}void ErrorHandling(char* message){fputs(message, stderr);fputc(\'\\n\', stderr);exit(1);}

结果:

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » (TCP IP网络编程)实验五 I/O复用模型编程