首页 > 代码库 > win32 select中的writefds

win32 select中的writefds

#define WIN32_LEAN_AND_MEAN#include <iostream>#include <iterator>#include <vector>#include <string>#include <time.h>#include <winsock2.h> #include <stdio.h> #define PORT       5122 #define MSGSIZE     1024 #pragma comment(lib, "ws2_32.lib") int     g_iTotalConn = 0;SOCKET g_CliSocketArr[FD_SETSIZE];DWORD WINAPI WorkerThread(LPVOID lpParameter);int main(){	WSADATA     wsaData;	DWORD       dwThreadId;	// Initialize Windows socket library   	WSAStartup(0x0202, &wsaData);   	// Create worker thread   	HANDLE hThread = CreateThread(NULL, 0, WorkerThread, NULL, 0, &dwThreadId);	WaitForSingleObject(hThread, INFINITE);	CloseHandle(hThread);	return 0;}DWORD WINAPI WorkerThread(LPVOID lpParam){	int             i;	fd_set         fdread;	fd_set		fdwrite;	fd_set		fdexp;	int             ret;	struct timeval tv = { 3, 0 };	char           szMessage[MSGSIZE];	for (int i = 0; i < 10; ++i)	{		SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);		// Bind  		SOCKADDR_IN local;		local.sin_addr.S_un.S_addr = inet_addr("206.246.122.250");//连接时间服务器		local.sin_family = AF_INET;		local.sin_port = htons(13);		g_CliSocketArr[g_iTotalConn++] = s;		int ret = connect(s, (sockaddr*)&local, sizeof(SOCKADDR));		printf("connnect ret = %d \n", ret);	}	int n = 0;	while (TRUE)	{		if (n++ >50)		{			break;		}		printf("loop %d\n", n);		FD_ZERO(&fdread);		FD_ZERO(&fdwrite);		FD_ZERO(&fdexp);		for (i = 0; i < g_iTotalConn; i++)		{			FD_SET(g_CliSocketArr[i], &fdread);			FD_SET(g_CliSocketArr[i], &fdwrite);			FD_SET(g_CliSocketArr[i], &fdexp);		}                     // We only care read event 		int tick = GetTickCount();		ret = select(0, &fdread, &fdwrite, &fdexp, &tv);//因为fdwrite中的socket一般都是可写的,所以都会立即返回,打印0		printf("select use %d tick \n", GetTickCount() - tick);//机子上打印都是		if (ret == 0)		{       // Time expired 			continue;		}		else if (ret < 0)		{			Sleep(100);			continue;		}		for (i = 0; i < g_iTotalConn; i++)		{			if (FD_ISSET(g_CliSocketArr[i], &fdread))			{         // A read event happened on g_CliSocketArr 				ret = recv(g_CliSocketArr[i], szMessage, MSGSIZE, 0);				if (ret == SOCKET_ERROR)				{					// Client socket closed           					printf("Client socket %d closed.\n", g_CliSocketArr[i]);					closesocket(g_CliSocketArr[i]);					if (i < g_iTotalConn - 1)					{						g_CliSocketArr[i--] = g_CliSocketArr[--g_iTotalConn];					}				}				else if (ret == 0)				{					continue;				}				else				{					// We received a message from client 					szMessage[ret] = ‘\0‘;					printf("[%s] from %d\n",szMessage, g_CliSocketArr[i]);									}			} //if			if (FD_ISSET(g_CliSocketArr[i], &fdwrite))			{				printf("write %d\n",g_CliSocketArr[i]);				send(g_CliSocketArr[i], "hello", strlen("hello"), 0);//注释掉这行代码的话会一直执行到这里printf,否则下次循环会有异常即会执行下面的代码			}			if (FD_ISSET(g_CliSocketArr[i], &fdexp))			{				printf("except %d\n",g_CliSocketArr[i]);				closesocket(g_CliSocketArr[i]);				if (i < g_iTotalConn - 1)				{					g_CliSocketArr[i--] = g_CliSocketArr[--g_iTotalConn];//可能是对端关闭socket造成				}			}		}//for 	}//while     	return 0;}

 socket中select里面的fdread不用解释,简单的就是被connection或者有数据需要recv时返回,而fdwrite的话如果socket内核写缓冲区可用的话会返回告知,具体看上面的代码,网上复制简单修改主要是用于验证,代码说明一切

win32 select中的writefds