亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? eventselectserver.h

?? 以線程池的方式設計服務器
?? H
字號:
/////////////////////////////////////////////////////
// EventSelectServer.h文件

DWORD WINAPI ServerThread(LPVOID lpParam);


// 套節字對象
typedef struct _SOCKET_OBJ
{
	SOCKET s;					// 套節字句柄
	HANDLE event;				// 與此套節字相關聯的事件對象句柄
	sockaddr_in addrRemote;		// 客戶端地址信息

	_SOCKET_OBJ *pNext;			// 指向下一個SOCKET_OBJ對象,為的是連成一個表
} SOCKET_OBJ, *PSOCKET_OBJ;

// 線程對象
typedef struct _THREAD_OBJ
{
	HANDLE events[WSA_MAXIMUM_WAIT_EVENTS];	// 記錄當前線程要等待的事件對象的句柄
	int nSocketCount;						// 記錄當前線程處理的套節字的數量 <=  WSA_MAXIMUM_WAIT_EVENTS

	PSOCKET_OBJ pSockHeader;				// 當前線程處理的套節字對象列表,pSockHeader指向表頭
	PSOCKET_OBJ pSockTail;					// pSockTail指向表尾

	CRITICAL_SECTION cs;					// 關鍵代碼段變量,為的是同步對本結構的訪問
	_THREAD_OBJ *pNext;						// 指向下一個THREAD_OBJ對象,為的是連成一個表

} THREAD_OBJ, *PTHREAD_OBJ;

// 線程列表
PTHREAD_OBJ g_pThreadList;		// 指向線程對象列表表頭
CRITICAL_SECTION g_cs;			// 同步對此全局變量的訪問


// 狀態信息
LONG g_nTatolConnections;		// 總共連接數量
LONG g_nCurrentConnections;		// 當前連接數量


// 申請一個套節字對象,初始化它的成員
PSOCKET_OBJ GetSocketObj(SOCKET s)	
{
	PSOCKET_OBJ pSocket = (PSOCKET_OBJ)::GlobalAlloc(GPTR, sizeof(SOCKET_OBJ));
	if(pSocket != NULL)
	{
		pSocket->s = s;
		pSocket->event = ::WSACreateEvent();
	}
	return pSocket;
}

// 釋放一個套節字對象
void FreeSocketObj(PSOCKET_OBJ pSocket)
{
	::CloseHandle(pSocket->event);
	if(pSocket->s != INVALID_SOCKET)
	{
		::closesocket(pSocket->s);
	}
	::GlobalFree(pSocket);
}

// 申請一個線程對象,初始化它的成員,并將它添加到線程對象列表中
PTHREAD_OBJ GetThreadObj()
{
	PTHREAD_OBJ pThread = (PTHREAD_OBJ)::GlobalAlloc(GPTR, sizeof(THREAD_OBJ));
	if(pThread != NULL)
	{	
		::InitializeCriticalSection(&pThread->cs);
		// 創建一個事件對象,用于指示該線程的句柄數組需要重組
		pThread->events[0] = ::WSACreateEvent();

		// 將新申請的線程對象添加到列表中
		::EnterCriticalSection(&g_cs);
		pThread->pNext = g_pThreadList;
		g_pThreadList = pThread;
		::LeaveCriticalSection(&g_cs);
	}
	return pThread;
}

// 釋放一個線程對象,并將它從線程對象列表中移除
void FreeThreadObj(PTHREAD_OBJ pThread)
{
	// 在線程對象列表中查找pThread所指的對象,如果找到就從中移除
	::EnterCriticalSection(&g_cs);
	PTHREAD_OBJ p = g_pThreadList;
	if(p == pThread)		// 是第一個?
	{
		g_pThreadList = p->pNext;
	}
	else
	{
		while(p != NULL && p->pNext != pThread)
		{
			p = p->pNext;
		}
		if(p != NULL)
		{
			// 此時,p是pThread的前一個,即“p->pNext == pThread”
			p->pNext = pThread->pNext;
		}
	}
	::LeaveCriticalSection(&g_cs);

	// 釋放資源
	::CloseHandle(pThread->events[0]);
	::DeleteCriticalSection(&pThread->cs);
	::GlobalFree(pThread);
}

// 重新建立線程對象的events數組
void RebuildArray(PTHREAD_OBJ pThread)	
{
	::EnterCriticalSection(&pThread->cs);
	PSOCKET_OBJ pSocket = pThread->pSockHeader;
	int n = 1;	// 從第1個開始寫,第0個用于指示需要重建了
	while(pSocket != NULL)
	{
		pThread->events[n++] = pSocket->event;
		pSocket = pSocket->pNext;
	}
	::LeaveCriticalSection(&pThread->cs);
}

/////////////////////////////////////////////////////////////////////

// 向一個線程的套節字列表中插入一個套節字
BOOL InsertSocketObj(PTHREAD_OBJ pThread, PSOCKET_OBJ pSocket)
{
	BOOL bRet = FALSE;
	::EnterCriticalSection(&pThread->cs);
	if(pThread->nSocketCount < WSA_MAXIMUM_WAIT_EVENTS - 1)
	{
		if(pThread->pSockHeader == NULL)
		{
			pThread->pSockHeader = pThread->pSockTail = pSocket;
		}
		else
		{
			pThread->pSockTail->pNext = pSocket;
			pThread->pSockTail = pSocket;
		}
		pThread->nSocketCount ++;
		bRet = TRUE;
	}
	::LeaveCriticalSection(&pThread->cs);

	// 插入成功,說明成功處理了客戶的連接請求
	if(bRet)
	{
		::InterlockedIncrement(&g_nTatolConnections);
		::InterlockedIncrement(&g_nCurrentConnections);
	}	
	return bRet;
}

// 將一個套節字對象安排給空閑的線程處理
void AssignToFreeThread(PSOCKET_OBJ pSocket)
{	
	pSocket->pNext = NULL;

	::EnterCriticalSection(&g_cs);
	PTHREAD_OBJ pThread = g_pThreadList;
	// 試圖插入到現存線程
	while(pThread != NULL)
	{
		if(InsertSocketObj(pThread, pSocket))
			break;
		pThread = pThread->pNext;
	}

	// 沒有空閑線程,為這個套節字創建新的線程
	if(pThread == NULL)
	{
		pThread = GetThreadObj();
		InsertSocketObj(pThread, pSocket);	
		::CreateThread(NULL, 0, ServerThread, pThread, 0, NULL);
	}
	::LeaveCriticalSection(&g_cs);

	// 指示線程重建句柄數組
	::WSASetEvent(pThread->events[0]);
}

// 從給定線程的套節字對象列表中移除一個套節字對象
void RemoveSocketObj(PTHREAD_OBJ pThread, PSOCKET_OBJ pSocket)
{
	::EnterCriticalSection(&pThread->cs);

	// 在套節字對象列表中查找指定的套節字對象,找到后將之移除
	PSOCKET_OBJ pTest = pThread->pSockHeader;
	if(pTest == pSocket)
	{
		if(pThread->pSockHeader == pThread->pSockTail)
			pThread->pSockTail = pThread->pSockHeader = pTest->pNext;
		else
			pThread->pSockHeader = pTest->pNext;
	}
	else
	{
		while(pTest != NULL && pTest->pNext != pSocket)
			pTest = pTest->pNext;
		if(pTest != NULL)
		{
			if(pThread->pSockTail == pSocket)
				pThread->pSockTail = pTest;
			pTest->pNext = pSocket->pNext;
		}
	}
	pThread->nSocketCount --;

	::LeaveCriticalSection(&pThread->cs);

	// 指示線程重建句柄數組
	::WSASetEvent(pThread->events[0]);

	// 說明一個連接中斷
	::InterlockedDecrement(&g_nCurrentConnections);
}


BOOL HandleIO(PTHREAD_OBJ pThread, PSOCKET_OBJ pSocket)
{
	// 獲取具體發生的網絡事件
	WSANETWORKEVENTS event;
	::WSAEnumNetworkEvents(pSocket->s, pSocket->event, &event);
	do
	{
		if(event.lNetworkEvents & FD_READ)			// 套節字可讀
		{
			if(event.iErrorCode[FD_READ_BIT] == 0)
			{
				char szText[256];
				int nRecv = ::recv(pSocket->s, szText, strlen(szText), 0);
				if(nRecv > 0)				
				{
					szText[nRecv] = '\0';
					printf("接收到數據:%s \n", szText);
				}
			}
			else
				break;
		}
		else if(event.lNetworkEvents & FD_CLOSE)	// 套節字關閉
		{
			break;
		}
		else if(event.lNetworkEvents & FD_WRITE)	// 套節字可寫
		{
			if(event.iErrorCode[FD_WRITE_BIT] == 0)
			{	
			}
			else
				break;
		}
		return TRUE;
	}
	while(FALSE);

	// 套節字關閉,或者有錯誤發生,程序都會轉到這里來執行
	RemoveSocketObj(pThread, pSocket);
	FreeSocketObj(pSocket);
	return FALSE;
}

PSOCKET_OBJ FindSocketObj(PTHREAD_OBJ pThread, int nIndex) // nIndex從1開始
{
	// 在套節字列表中查找
	PSOCKET_OBJ pSocket = pThread->pSockHeader;
	while(--nIndex)
	{
		if(pSocket == NULL)
			return NULL;
		pSocket = pSocket->pNext;
	}
	return pSocket;
}

DWORD WINAPI ServerThread(LPVOID lpParam)
{
	// 取得本線程對象的指針
	PTHREAD_OBJ pThread = (PTHREAD_OBJ)lpParam;
	while(TRUE)
	{
		//	等待網絡事件
		int nIndex = ::WSAWaitForMultipleEvents(
							pThread->nSocketCount + 1, pThread->events, FALSE, WSA_INFINITE, FALSE);
		nIndex = nIndex - WSA_WAIT_EVENT_0;
		// 查看受信的事件對象
		for(int i=nIndex; i<pThread->nSocketCount + 1; i++)
		{
			nIndex = ::WSAWaitForMultipleEvents(1, &pThread->events[i], TRUE, 1000, FALSE);
			if(nIndex == WSA_WAIT_FAILED || nIndex == WSA_WAIT_TIMEOUT)
			{
				continue;
			}
			else
			{
				if(i == 0)				// events[0]受信,重建數組
				{
					RebuildArray(pThread);
					// 如果沒有客戶I/O要處理了,則本線程退出
					if(pThread->nSocketCount == 0)
					{
						FreeThreadObj(pThread);
						return 0;
					}
					::WSAResetEvent(pThread->events[0]);
				}
				else					// 處理網絡事件
				{
					// 查找對應的套節字對象指針,調用HandleIO處理網絡事件
					PSOCKET_OBJ pSocket = (PSOCKET_OBJ)FindSocketObj(pThread, i);
					if(pSocket != NULL)
					{
						if(!HandleIO(pThread, pSocket))
							RebuildArray(pThread);
					}
					else
						printf(" Unable to find socket object \n ");
				}
			}
		}
	}
	return 0;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人黄色777网| 狠狠狠色丁香婷婷综合激情| 亚洲精品一区二区三区在线观看| 91久久免费观看| 不卡一区二区三区四区| 成人一区二区三区中文字幕| 激情六月婷婷久久| 国产一区在线不卡| 成人激情文学综合网| 丁香一区二区三区| 99精品黄色片免费大全| 色综合久久久久久久久久久| a级精品国产片在线观看| av男人天堂一区| 色噜噜狠狠色综合中国| 欧美午夜电影网| 日韩午夜中文字幕| 欧美成人艳星乳罩| 日本一区二区免费在线观看视频 | 欧美激情在线观看视频免费| 亚洲精品一区二区三区影院| 国产欧美日韩在线视频| 国产精品久久二区二区| 亚洲国产一区二区在线播放| 亚洲成人免费视| 麻豆精品一二三| 成人黄色一级视频| 欧美日韩亚洲综合| 久久精品日产第一区二区三区高清版 | 美女精品一区二区| 国产精品资源在线| 欧美中文字幕一区二区三区| 精品欧美黑人一区二区三区| 中文字幕亚洲欧美在线不卡| 亚洲高清不卡在线| 国产一区二区三区最好精华液| 成人免费观看视频| 欧美日韩国产经典色站一区二区三区| 日韩一级片在线观看| 国产精品免费av| 亚洲午夜影视影院在线观看| 精品写真视频在线观看| 色伊人久久综合中文字幕| 日韩一区二区三区免费看| 国产精品美女久久久久av爽李琼| 亚洲午夜激情av| 国产成人免费视频精品含羞草妖精 | 国产免费成人在线视频| 婷婷激情综合网| 成人av午夜电影| 欧美sm美女调教| 亚欧色一区w666天堂| bt7086福利一区国产| 精品av久久707| 日韩国产精品大片| 一本久道久久综合中文字幕| 中文字幕高清不卡| 精久久久久久久久久久| 宅男噜噜噜66一区二区66| 亚洲精品乱码久久久久| 大白屁股一区二区视频| 精品国精品国产| 日本欧美韩国一区三区| 欧美综合在线视频| 亚洲伦理在线免费看| 91视频国产资源| 综合婷婷亚洲小说| 丁香六月久久综合狠狠色| 久久免费午夜影院| 精品亚洲免费视频| 日韩精品专区在线影院观看| 午夜精品一区二区三区免费视频 | 精品国免费一区二区三区| 日韩福利电影在线| 制服丝袜成人动漫| 视频一区中文字幕国产| 欧美高清www午色夜在线视频| 一区二区三区不卡在线观看| 色欲综合视频天天天| 中文字幕在线不卡视频| 国产盗摄一区二区| 中文字幕第一区二区| 成人免费av在线| 国产精品久线观看视频| 成人精品小蝌蚪| 自拍偷在线精品自拍偷无码专区| 波多野结衣亚洲| 亚洲激情自拍偷拍| 欧美日韩在线不卡| 毛片av一区二区| 久久久久久电影| 99久久精品国产一区| 亚洲三级在线播放| 欧美人与禽zozo性伦| 日韩电影在线观看一区| 日韩女优电影在线观看| 国产精品一二三区| 成人免费在线播放视频| 在线免费一区三区| 青青草97国产精品免费观看 | 日韩精品1区2区3区| 欧美一级国产精品| 国产不卡视频一区二区三区| 国产精品久久久久久久久快鸭| 91网站最新地址| 日韩不卡在线观看日韩不卡视频| 26uuuu精品一区二区| 99久久精品免费看| 免费成人在线观看视频| 国产精品视频观看| 欧美日韩国产区一| 国产麻豆视频一区| 亚洲国产视频一区二区| 欧美不卡一区二区三区四区| 99视频超级精品| 久久精工是国产品牌吗| 中文字幕在线不卡一区| 欧美成人一区二区三区在线观看 | 久久超碰97中文字幕| 亚洲欧洲日产国码二区| 欧美二区在线观看| 成人综合在线网站| 青青草原综合久久大伊人精品优势 | 韩国一区二区三区| 伊人性伊人情综合网| 久久先锋影音av鲁色资源网| 欧洲另类一二三四区| 成人一道本在线| 蜜桃一区二区三区在线| 亚洲美女精品一区| 国产女人水真多18毛片18精品视频| 欧美三级电影在线看| 成人丝袜高跟foot| 精品一区二区久久久| 午夜欧美2019年伦理| 亚洲精品伦理在线| 中文幕一区二区三区久久蜜桃| 91精品国产高清一区二区三区蜜臀| av日韩在线网站| 粉嫩绯色av一区二区在线观看 | 亚洲欧美另类图片小说| 久久久久国色av免费看影院| 欧美一级黄色片| 欧美一区二区在线看| 欧美性色欧美a在线播放| 91亚洲永久精品| av亚洲产国偷v产偷v自拍| 国产尤物一区二区| 久久99精品国产91久久来源| 人人精品人人爱| 免费看日韩精品| 秋霞成人午夜伦在线观看| 亚洲一区二区高清| 亚洲午夜免费视频| 亚洲成人免费在线观看| 夜色激情一区二区| 亚洲妇女屁股眼交7| 亚洲国产日韩a在线播放| 亚洲高清免费视频| 日韩**一区毛片| 看电视剧不卡顿的网站| 久久电影国产免费久久电影| 久久精品国内一区二区三区| 久久草av在线| 国产乱子伦一区二区三区国色天香| 久久精品国产一区二区三区免费看| 免费的国产精品| 国产精品中文字幕日韩精品| 国产精品1区二区.| 成人app软件下载大全免费| 97se亚洲国产综合自在线不卡 | 激情伊人五月天久久综合| 老汉av免费一区二区三区 | 《视频一区视频二区| 亚洲精品视频在线看| 亚洲第一成人在线| 免费观看91视频大全| 国产麻豆日韩欧美久久| 91麻豆福利精品推荐| 欧美色电影在线| 精品va天堂亚洲国产| 国产精品高潮呻吟| 天天色 色综合| 国产一区不卡视频| 色婷婷精品大在线视频| 91精品国产一区二区三区| 国产欧美日韩一区二区三区在线观看| 亚洲三级久久久| 另类的小说在线视频另类成人小视频在线 | 久久久精品国产99久久精品芒果| 国产欧美精品一区| 首页国产丝袜综合| www.欧美亚洲| 日韩女优视频免费观看| 亚洲欧洲中文日韩久久av乱码| 日韩中文字幕av电影| 成人免费视频caoporn| 91精品国产91久久综合桃花| 日本一区二区三区国色天香| 日韩在线a电影|