码迷,mamicode.com
首页 > Windows程序 > 详细

win32 select中的writefds

时间:2015-01-17 16:31:19      阅读:256      评论:0      收藏:0      [点我收藏+]

标签:

#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

标签:

原文地址:http://www.cnblogs.com/UnGeek/p/4230504.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!