socket编程基于IO复用的多客户端服务器

来源:互联网 发布:淘宝借贷平台 编辑:程序博客网 时间:2024/05/16 00:26
很久没更新了,今天写了一个windows下的 socket编程基于IO复用的多客户端服务器 , 重点在于select 函数,自行百度就可以了。
Talk is cheap , show me the code.

server.c
#include<stdlib.h>#include<stdio.h>#include<WinSock2.h>#define BUFSIZ 10#pragma comment(lib,"ws2_32.lib")void ErrorHandling(char * msg){puts(msg);system("pause");exit(1);}int main(){WSADATA wsd;SOCKET hServSock, hClntSock;SOCKADDR_IN servAdr, clntAdr;TIMEVAL timeout;fd_set reads, cpyReads;int adrSz;int strLen, fdNum;unsigned int i;char buf[BUFSIZ];//初始化socket库if (WSAStartup(MAKEWORD(2, 2), &wsd) != 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_un.S_addr = inet_addr("127.0.0.1");servAdr.sin_port = htons(6000);if (bind(hServSock,(SOCKADDR *)&servAdr,sizeof(SOCKADDR))==SOCKET_ERROR){ErrorHandling("bind() error");}if (listen(hServSock,5)==SOCKET_ERROR){ErrorHandling("listen() error");}hClntSock = socket(PF_INET, SOCK_STREAM, 0);FD_ZERO(&reads);FD_SET(hServSock, &reads);/*FD_SET(hClntSock, &reads);printf("%d",reads.fd_count);for (i = 0; i < reads.fd_count;i++){printf("%d",reads.fd_array[i]);}*/while (1){cpyReads = reads;timeout.tv_sec = 5;timeout.tv_usec = 0;fdNum = select(0, &cpyReads, 0, 0, &timeout);if (fdNum==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){adrSz = sizeof(clntAdr);hClntSock = accept(hServSock, (SOCKADDR*)&clntAdr, &adrSz);FD_SET(hClntSock, &reads);printf("connected client: %d \n", hClntSock);} else{//memset(buf, 0, BUFSIZ);do{memset(buf, 0, BUFSIZ);strLen = recv(reads.fd_array[i], buf, BUFSIZ - 1, 0);if (strLen == 0 || strLen == -1){FD_CLR(reads.fd_array[i], &reads);closesocket(cpyReads.fd_array[i]);printf("closed client:%d \n", cpyReads.fd_array[i]);}else{printf("From %d : %s", cpyReads.fd_array[i], buf);//send(reads.fd_array[i], buf, strLen, 0);}} while (strLen==BUFSIZ-1);;/*if (strLen == 0 || strLen ==-1){FD_CLR(reads.fd_array[i], &reads);closesocket(cpyReads.fd_array[i]);printf("closed client:%d \n", cpyReads.fd_array[i]);}else{printf("From %d : %s",cpyReads.fd_array[i],buf);send(reads.fd_array[i], buf, strLen, 0);}*/}}}}closesocket(hServSock);WSACleanup();return 0;}

client.c  (这里的客户端和之前的一样,没有改变)
#include<stdlib.h>#include<stdio.h>#include<WinSock2.h>#pragma comment(lib,"ws2_32.lib")void ErrorHandling(char * msg){puts(msg);system("pause");exit(1);}int main(){WSADATA wsd;SOCKET  sClient;SOCKADDR_IN addrClient;int sizeAddrClient = 0;int recvCount = 100;char charBuf[1024] = {0};//初始化socket库if (WSAStartup(MAKEWORD(2, 2), &wsd)!=0){ErrorHandling("WSAStartup error!");}puts("初始化socket库");//创建客户端socketsClient = socket(AF_INET, SOCK_STREAM, 0);if (sClient==INVALID_SOCKET){ErrorHandling("socket() error!");}puts("创建客户端socket");//初始化网络地址信息memset(&addrClient, 0, sizeof(addrClient));addrClient.sin_family = AF_INET;addrClient.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");addrClient.sin_port = htons(6000);puts("初始化网络地址信息");//连接服务端if (connect(sClient,(SOCKADDR*)&addrClient,sizeof(addrClient))==SOCKET_ERROR){ErrorHandling("connect error!");}puts("现在可以向服务端发送消息");//循环发送消息(我规定最多为200次)while (recvCount>0){memset(charBuf, 0, 1024);printf("To:");gets(charBuf);send(sClient, charBuf, strlen(charBuf), 0);memset(charBuf, 0, 1024);recvCount--;}//关闭socketclosesocket(sClient);WSACleanup();puts("关闭socket");system("pause");return 0;}
不明白的地方请留言


0 0