Windows socket I/O模型 之 select(1)
2014-04-11 10:50
120 查看
参考1:http://blog.csdn.net/zjsiva/article/details/5895087
我喜欢直接上代码,请看,在上述代码增加了一些内容。
比如服务器自动回复客户机请求。
// 服务器
// 客户机
我喜欢直接上代码,请看,在上述代码增加了一些内容。
比如服务器自动回复客户机请求。
// 服务器
// Select_Server.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <stdio.h> #include <string.h> #include <WINSOCK2.H> #pragma comment(lib,"ws2_32.lib") #define STR_SERVER_IP "127.0.0.1" #define INT_SERVER_PORT 6002 #define INT_DATABUFFER_SIZE 256 int _tmain(int argc, _TCHAR* argv[]) { WORD dwVersion = MAKEWORD(2,2); WSAData wsaData; WSAStartup(WINSOCK_VERSION,&wsaData); SOCKET sockServer = socket(AF_INET, SOCK_STREAM, 0); if (INVALID_SOCKET == sockServer) { printf("Failed to create socket!\r\n"); WSACleanup(); return -1; } sockaddr_in addrServer; memset(&addrServer,0,sizeof(sockaddr_in)); addrServer.sin_family = AF_INET; addrServer.sin_port = htons(INT_SERVER_PORT); addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //addrServer.sin_addr.s_addr = htonl(INADDR_ANY); int iResult; bool bReuseAddr = true; iResult=setsockopt(sockServer,SOL_SOCKET,SO_REUSEADDR,(char *)&bReuseAddr,sizeof(bReuseAddr)); if(SOCKET_ERROR == iResult) { printf("Failed to set resueaddr socket!\r\n"); WSACleanup(); return -1; } /* unsigned long cmd = 1; iResult= ioctlsocket(sockServer,FIONBIO,&cmd); */ iResult = bind(sockServer,(sockaddr *)&addrServer,sizeof(addrServer)); if (SOCKET_ERROR == iResult) { printf("Failed to bind address!\r\n"); WSACleanup(); return -1; } if (0 != listen(sockServer,5)) { printf("Failed to listen client!\r\n"); WSACleanup(); return -1; } UINT i = 0; SOCKET sockAccept; sockaddr_in addrAccept; int iAcceptLen = sizeof(addrAccept); char szDataBuff[INT_DATABUFFER_SIZE]; int iRecvSize; sockaddr_in addrTemp; int iTempLen; fd_set fd; FD_ZERO(&fd); FD_SET(sockServer, &fd); /* timeval tm; tm.tv_sec = 0; tm.tv_usec = 1000; */ printf("Start server...\r\n"); while(1) { fd_set fdOld = fd; iResult = select(0, &fdOld, NULL, NULL, /*&tm*/NULL); if (0 <= iResult) { for(i = 0; i < fd.fd_count; i++) { if (FD_ISSET(fd.fd_array[i], &fdOld)) { //如果socket是服务器,则接收连接 if (fd.fd_array[i] == sockServer) { memset(&addrAccept,0,sizeof(addrTemp)); sockAccept = accept(sockServer, (sockaddr *)&addrAccept, &iAcceptLen); if (INVALID_SOCKET != sockAccept) { FD_SET(sockAccept, &fd); //FD_SET(sockAccept,&fdOld); printf("%s:%d has connected server!\r\n", inet_ntoa(addrAccept.sin_addr), ntohs(addrAccept.sin_port)); } } else { //非服务器,接收数据(因为fd是读数据集) memset(szDataBuff, 0, INT_DATABUFFER_SIZE); iRecvSize = recv(fd.fd_array[i], szDataBuff, INT_DATABUFFER_SIZE, 0); memset(&addrTemp, 0, sizeof(addrTemp)); iTempLen = sizeof(addrTemp); getpeername(fd.fd_array[i], (sockaddr *)&addrTemp, &iTempLen); // an error occurs if (SOCKET_ERROR == iRecvSize) { closesocket(fd.fd_array[i]); FD_CLR(fd.fd_array[i], &fd); i--; printf("Failed to recv data ,%s:%d errorcode:%d.\r\n", inet_ntoa(addrTemp.sin_addr),ntohs(addrTemp.sin_port),WSAGetLastError()); continue; } // 客户socket关闭 if (0 == iRecvSize) { printf("%s:%d has closed!\r\n",inet_ntoa(addrTemp.sin_addr), ntohs(addrTemp.sin_port)); closesocket(fd.fd_array[i]); FD_CLR(fd.fd_array[i],&fd); i--; } // no error occurs, returns the number of bytes received if (0 < iRecvSize) { printf("recv %s:%d data:%s\r\n", inet_ntoa(addrTemp.sin_addr), ntohs(addrTemp.sin_port),szDataBuff); char szEcho[256] = {0}; sprintf(szEcho, "Server has got: %s.", szDataBuff); send(fd.fd_array[i], szEcho, strlen(szEcho), 0); } } } } } else if (SOCKET_ERROR == iResult) { int iErr = WSAGetLastError(); //WSACleanup(); printf("Faild to select sockt in server!(Error: %d)\r\n", iErr); Sleep(100); } } WSACleanup(); return 0; }
// 客户机
// Select_Client.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <stdio.h> #include <string.h> #include <WINSOCK2.H> #pragma comment(lib,"ws2_32.lib") #define INT_SERVER_PORT 6002 #define STR_SERVER_IP "127.0.0.1" #define INT_DATABUFFER_SIZE 256 #define STR_EXIT "exit" #define STR_RECV "recv" void main(void) { WSAData wsaData; WSAStartup(WINSOCK_VERSION,&wsaData); SOCKET sockClient = socket(AF_INET,SOCK_STREAM,0); if (INVALID_SOCKET == sockClient) { printf("Failed to create client!\r\n"); WSACleanup(); } sockaddr_in addrClient; addrClient.sin_addr.S_un.S_addr = inet_addr(STR_SERVER_IP); addrClient.sin_family = AF_INET; addrClient.sin_port = htons(INT_SERVER_PORT); int iResult; iResult = connect(sockClient,(sockaddr *)&addrClient,sizeof(sockaddr_in)); if (SOCKET_ERROR == iResult) { printf("Failed to connect server!\r\n"); WSACleanup(); return; } if (0 != iResult) { int iErrorCode; iErrorCode = WSAGetLastError(); printf("Failed to connect server,error:%d.\r\n",iErrorCode); WSACleanup(); return; } char szDataBuffer[INT_DATABUFFER_SIZE]; while(1) { memset(szDataBuffer,0,INT_DATABUFFER_SIZE); scanf("%s",szDataBuffer); if (0 == strcmp(szDataBuffer, STR_EXIT)) { printf("The client has stopped!\r\n"); break; } else if( 0 == strcmp(szDataBuffer, STR_RECV)) { int ret = recv(sockClient, szDataBuffer, 256, 0); printf("Recv server echo: %s\r\n", szDataBuffer); } else { if (1 > send(sockClient, szDataBuffer, strlen(szDataBuffer),0)) { printf("Failed to send data!\r\n"); } } Sleep(100); } closesocket(sockClient); WSACleanup(); }这里需要注意的就是 fd_set, FD_ZERO,FD_SET,FD_ISSET这几个宏的用法。
相关文章推荐
- windows socket----select模型
- windows socket----select模型
- Windows socket之Select模型开发
- Windows socket之Select模型开发
- Windows socket之WSAEventSelect模型
- Windows Socket五种I/O模型(一)——选择模型(Select)
- Windows socket I/O模型 之 select(2)
- Windows Socket五种I/O模型(一)——选择模型(Select)
- vc++ windows socket I/O模型 WSAeventSelect 模型例子
- Windows socket I/O模型 之 select(1)
- windows socket编程select模型使用
- Windows Socket I/O模型之 Select模式
- Windows socket I/O模型 之 select(2)
- Windows socket I/O模型 之 select(2)
- Windows socket之Select模型开发
- Windows Socket五种I/O模型——select模型
- Windows Socket I/O模型之 WSAAsyncSelect模式
- windows socket----select模型
- windows Socket编程之select网络模型
- Windows Socket I/O模型之 WSAEventSelect模式