select()实现
来源:互联网 发布:软件测试的基本技能 编辑:程序博客网 时间:2024/05/15 22:27
#include <winsock2.h>#include <windows.h>#include <stdio.h>#define PORT 5150#define DATA_BUFSIZE 8192typedef struct _SOCKET_INFORMATION { CHAR Buffer[DATA_BUFSIZE]; WSABUF DataBuf; SOCKET Socket; OVERLAPPED Overlapped; DWORD BytesSEND; DWORD BytesRECV;} SOCKET_INFORMATION, * LPSOCKET_INFORMATION;BOOL CreateSocketInformation(SOCKET s);void FreeSocketInformation(DWORD Index);DWORD TotalSockets = 0;LPSOCKET_INFORMATION SocketArray[FD_SETSIZE];void main(void){ SOCKET ListenSocket; SOCKET AcceptSocket; SOCKADDR_IN InternetAddr; WSADATA wsaData; INT Ret; FD_SET WriteSet; FD_SET ReadSet; DWORD i; DWORD Total; ULONG NonBlock; DWORD Flags; DWORD SendBytes; DWORD RecvBytes; if ((Ret = WSAStartup(0x0202,&wsaData)) != 0) { printf("WSAStartup() failed with error %d\n", Ret); WSACleanup(); return; } // Prepare a socket to listen for connections. if ((ListenSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) { printf("WSASocket() failed with error %d\n", WSAGetLastError()); return; } InternetAddr.sin_family = AF_INET; InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY); InternetAddr.sin_port = htons(PORT); if (bind(ListenSocket, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR) { printf("bind() failed with error %d\n", WSAGetLastError()); return; } if (listen(ListenSocket, 5)) { printf("listen() failed with error %d\n", WSAGetLastError()); return; } // Change the socket mode on the listening socket from blocking to // non-block so the application will not block waiting for requests. NonBlock = 1; if (ioctlsocket(ListenSocket, FIONBIO, &NonBlock) == SOCKET_ERROR) { printf("ioctlsocket() failed with error %d\n", WSAGetLastError()); return; } while(TRUE) { // Prepare the Read and Write socket sets for network I/O notification. FD_ZERO(&ReadSet); FD_ZERO(&WriteSet); // Always look for connection attempts. FD_SET(ListenSocket, &ReadSet); // Set Read and Write notification for each socket based on the // current state the buffer. If there is data remaining in the // buffer then set the Write set otherwise the Read set. for (i = 0; i < TotalSockets; i++) if (SocketArray[i]->BytesRECV > SocketArray[i]->BytesSEND) FD_SET(SocketArray[i]->Socket, &WriteSet); else FD_SET(SocketArray[i]->Socket, &ReadSet); if ((Total = select(0, &ReadSet, &WriteSet, NULL, NULL)) == SOCKET_ERROR) { printf("select() returned with error %d\n", WSAGetLastError()); return; } // Check for arriving connections on the listening socket. if (FD_ISSET(ListenSocket, &ReadSet)) { Total--; if ((AcceptSocket = accept(ListenSocket, NULL, NULL)) != INVALID_SOCKET) { // Set the accepted socket to non-blocking mode so the server will // not get caught in a blocked condition on WSASends NonBlock = 1; if (ioctlsocket(AcceptSocket, FIONBIO, &NonBlock) == SOCKET_ERROR) { printf("ioctlsocket() failed with error %d\n", WSAGetLastError()); return; } if (CreateSocketInformation(AcceptSocket) == FALSE) return; } else { if (WSAGetLastError() != WSAEWOULDBLOCK) { printf("accept() failed with error %d\n", WSAGetLastError()); return; } } } // Check each socket for Read and Write notification until the number // of sockets in Total is satisfied. for (i = 0; Total > 0 && i < TotalSockets; i++) { LPSOCKET_INFORMATION SocketInfo = SocketArray[i]; // If the ReadSet is marked for this socket then this means data // is available to be read on the socket. if (FD_ISSET(SocketInfo->Socket, &ReadSet)) { Total--; SocketInfo->DataBuf.buf = SocketInfo->Buffer; SocketInfo->DataBuf.len = DATA_BUFSIZE; Flags = 0; if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes, &Flags, NULL, NULL) == SOCKET_ERROR) { if (WSAGetLastError() != WSAEWOULDBLOCK) { printf("WSARecv() failed with error %d\n", WSAGetLastError()); FreeSocketInformation(i); } continue; } else { SocketInfo->BytesRECV = RecvBytes; // If zero bytes are received, this indicates the peer closed the // connection. if (RecvBytes == 0) { FreeSocketInformation(i); continue; } } } // If the WriteSet is marked on this socket then this means the internal // data buffers are available for more data. if (FD_ISSET(SocketInfo->Socket, &WriteSet)) { Total--; SocketInfo->DataBuf.buf = SocketInfo->Buffer + SocketInfo->BytesSEND; SocketInfo->DataBuf.len = SocketInfo->BytesRECV - SocketInfo->BytesSEND; if (WSASend(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &SendBytes, 0, NULL, NULL) == SOCKET_ERROR) { if (WSAGetLastError() != WSAEWOULDBLOCK) { printf("WSASend() failed with error %d\n", WSAGetLastError()); FreeSocketInformation(i); } continue; } else { SocketInfo->BytesSEND += SendBytes; if (SocketInfo->BytesSEND == SocketInfo->BytesRECV) { SocketInfo->BytesSEND = 0; SocketInfo->BytesRECV = 0; } } } } }}BOOL CreateSocketInformation(SOCKET s){ LPSOCKET_INFORMATION SI; printf("Accepted socket number %d\n", s); if ((SI = (LPSOCKET_INFORMATION) GlobalAlloc(GPTR, sizeof(SOCKET_INFORMATION))) == NULL) { printf("GlobalAlloc() failed with error %d\n", GetLastError()); return FALSE; } // Prepare SocketInfo structure for use. SI->Socket = s; SI->BytesSEND = 0; SI->BytesRECV = 0; SocketArray[TotalSockets] = SI; TotalSockets++; return(TRUE);}void FreeSocketInformation(DWORD Index){ LPSOCKET_INFORMATION SI = SocketArray[Index]; DWORD i; closesocket(SI->Socket); printf("Closing socket number %d\n", SI->Socket); GlobalFree(SI); // Squash the socket array for (i = Index; i < TotalSockets; i++) { SocketArray[i] = SocketArray[i + 1]; } TotalSockets--;}
0 0
- select()实现
- Select下拉实现比较
- select()实现分析
- JS select实现跳转
- select 实现readonly效果
- select server 实现
- select模型的实现
- select 实现超时连接
- epoll 实现 select接口
- js实现select跳转
- select编程实现
- select服务端代码实现
- CSS实现select样式
- select模型实现分析
- select实现多路复用
- Select实现并发服务器
- 实现自定义select标签
- select服务器简单实现
- ios第3天的气泡作业
- 【HDU】 2602 Bone Collector
- 关于共享内存的使用
- 程序猿之华丽转身:菜鸟4步曲!
- C和C++语言编程里面常用函数或者编程技巧总结(不断更新)
- select()实现
- 电容式触控芯片FAQ
- 【HDU】 2191 救灾
- Android学习路线
- auto_ptr STL智能指针
- word2vec 背景知识
- 互联网时代100本必读书,来自100位业界大咖推荐
- 在线进行复杂数学计算的网站——云算子
- Redis内存节省策略