一.实验目的
(1)熟悉Linux环境下数据报套接字编程的基本模型、函数使用细节等,掌握Linux环境下数据报套接字编程的具体过程。
(2)熟悉Windows环境下数据报套接字编程的基本模型、函数使用细节等,掌握Windows环境下数据报套接字编程的具体过程。
二.实验内容
(1) 使用数据报套接字实现一个Linux环境下的迭代回声服务器端(及客户端);
(2) 使用数据报套接字实现一个Windows环境下的迭代回声服务器端(及客户端)。
(3) 编写程序使服务器端和客户端可流收发消息。收发的消息均要输出到控制台窗口。
三.实验过程
Linux实现代码:
Uchar_server.c:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <sys/socket.h>#define BUF_SIZE 30void error_handling(char *message);int main(int argc, char *argv[]){int serv_sock;char message[BUF_SIZE];int str_len;socklen_t clnt_adr_sz;struct sockaddr_in serv_adr, clnt_adr;if(argc!=2){printf(\"Usage : %s <port>\\n\", argv[0]);exit(1);}serv_sock=socket(PF_INET, SOCK_DGRAM, 0);if(serv_sock==-1)error_handling(\"UDP socket creation error\");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\");clnt_adr_sz=sizeof(clnt_adr);while(1){str_len=recvfrom(serv_sock, message, BUF_SIZE, 0,(struct sockaddr*)&clnt_adr, &clnt_adr_sz);message[str_len]=0;printf(\"Message from client: %s\", message);fputs(\"Insert message(q to quit): \", stdout);fgets(message, sizeof(message), stdin);if(!strcmp(message,\"q\\n\") || !strcmp(message,\"Q\\n\"))break;sendto(serv_sock, message, strlen(message), 0,(struct sockaddr*)&clnt_adr, clnt_adr_sz);}close(serv_sock);return 0;}void error_handling(char *message){fputs(message, stderr);fputc(\'\\n\', stderr);exit(1);}Uchar_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 30void error_handling(char *message);int main(int argc, char *argv[]){int sock;char message[BUF_SIZE];int str_len;socklen_t adr_sz;struct sockaddr_in serv_adr, from_adr;if(argc!=3){printf(\"Usage : %s <IP> <port>\\n\", argv[0]);exit(1);}sock=socket(PF_INET, SOCK_DGRAM, 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]));while(1){fputs(\"Insert message(q to quit): \", stdout);fgets(message, sizeof(message), stdin);if(!strcmp(message,\"q\\n\") || !strcmp(message,\"Q\\n\"))break;sendto(sock, message, strlen(message), 0,(struct sockaddr*)&serv_adr, sizeof(serv_adr));adr_sz=sizeof(from_adr);str_len=recvfrom(sock, message, BUF_SIZE, 0,(struct sockaddr*)&from_adr, &adr_sz);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);}
结果:
Windows实现代码:
server.c:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <winsock2.h>#define BUF_SIZE 30void ErrorHandling(char* message);int main(int argc, char* argv[]){WSADATA wsaData;SOCKET servSock;char message[BUF_SIZE];int strLen;int clntAdrSz;SOCKADDR_IN servAdr, clntAdr;if (argc != 2) {printf(\"Usage : %s <port>\\n\", argv[0]);exit(1);}if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)ErrorHandling(\"WSAStartup() error!\");servSock = socket(PF_INET, SOCK_DGRAM, 0);if (servSock == INVALID_SOCKET)ErrorHandling(\"UDP socket creation error\");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(servSock, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)ErrorHandling(\"bind() error\");// while(1)// {// clntAdrSz=sizeof(clntAdr);// strLen=recvfrom(servSock, message, BUF_SIZE, 0,// (SOCKADDR*)&clntAdr, &clntAdrSz);// sendto(servSock, message, strLen, 0,// (SOCKADDR*)&clntAdr, sizeof(clntAdr));// }clntAdrSz = sizeof(clntAdr);while (1){strLen = recvfrom(servSock, message, BUF_SIZE, 0,(struct sockaddr*) & clntAdr, &clntAdrSz);message[strLen] = 0;printf(\"Message from client: %s\", message);fputs(\"Insert message(q to quit): \", stdout);fgets(message, sizeof(message), stdin);if (!strcmp(message, \"q\\n\") || !strcmp(message, \"Q\\n\"))break;sendto(servSock, message, strlen(message), 0,(struct sockaddr*) & clntAdr, clntAdrSz);}closesocket(servSock);WSACleanup();return 0;}void ErrorHandling(char* message){fputs(message, stderr);fputc(\'\\n\', stderr);exit(1);}Client.c:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <winsock2.h>#define BUF_SIZE 30void ErrorHandling(char* message);int main(int argc, char* argv[]){WSADATA wsaData;SOCKET sock;char message[BUF_SIZE];int strLen;int clntAdrSz;SOCKADDR_IN servAdr, from_adr;if (argc != 3) {printf(\"Usage : %s <IP> <port>\\n\", argv[0]);exit(1);}if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)ErrorHandling(\"WSAStartup() error!\");sock = socket(PF_INET, SOCK_DGRAM, 0);if (sock == 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]));connect(sock, (SOCKADDR*)&servAdr, sizeof(servAdr));// while (1)// {// fputs(\"Insert message(q to quit): \", stdout);// fgets(message, sizeof(message), stdin);// if (!strcmp(message, \"q\\n\") || !strcmp(message, \"Q\\n\"))// break;//// send(sock, message, strlen(message), 0);// strLen = recv(sock, message, sizeof(message) - 1, 0);//// message[strLen] = 0;// printf(\"Message from server: %s\", message);// }while (1){fputs(\"Insert message(q to quit): \", stdout);fgets(message, sizeof(message), stdin);if (!strcmp(message, \"q\\n\") || !strcmp(message, \"Q\\n\"))break;sendto(sock, message, strlen(message), 0,(struct sockaddr*) & servAdr, sizeof(servAdr));clntAdrSz = sizeof(from_adr);strLen = recvfrom(sock, message, BUF_SIZE, 0,(struct sockaddr*) & from_adr, &clntAdrSz);message[strLen] = 0;printf(\"Message from server: %s\", message);}closesocket(sock);WSACleanup();return 0;}void ErrorHandling(char* message){fputs(message, stderr);fputc(\'\\n\', stderr);exit(1);}
结果: