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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? overlappedserver.cpp

?? 使用windows的重疊I/O模型制作的網(wǎng)絡(luò)聊天服務(wù)器程序
?? CPP
字號:
///////////////////////////////////////////////////////
// OverlappedServer.cpp文件

#include "../common/initsock.h"

#include <Mswsock.h>
#include <stdio.h>
#include <windows.h>

CInitSock theSock;

#define BUFFER_SIZE 1024

typedef struct _SOCKET_OBJ
{
	SOCKET s;						// 套節(jié)字句柄
	int nOutstandingOps;			// 記錄此套節(jié)字上的重疊I/O數(shù)量
	
	LPFN_ACCEPTEX lpfnAcceptEx;		// 擴(kuò)展函數(shù)AcceptEx的指針(僅對監(jiān)聽套節(jié)字而言)
} SOCKET_OBJ, *PSOCKET_OBJ;

typedef struct _BUFFER_OBJ
{	
	OVERLAPPED ol;			// 重疊結(jié)構(gòu)
	char *buff;				// send/recv/AcceptEx所使用的緩沖區(qū)
	int nLen;				// buff的長度
	PSOCKET_OBJ pSocket;	// 此I/O所屬的套節(jié)字對象

	int nOperation;			// 提交的操作類型
#define OP_ACCEPT	1
#define OP_READ		2
#define OP_WRITE	3

	SOCKET sAccept;			// 用來保存AcceptEx接受的客戶套節(jié)字(僅對監(jiān)聽套節(jié)字而言)
	_BUFFER_OBJ *pNext;
} BUFFER_OBJ, *PBUFFER_OBJ;

HANDLE g_events[WSA_MAXIMUM_WAIT_EVENTS];	// I/O事件句柄數(shù)組
int g_nBufferCount;							// 上數(shù)組中有效句柄數(shù)量
PBUFFER_OBJ g_pBufferHead, g_pBufferTail;	// 記錄緩沖區(qū)對象組成的表的地址

// 申請?zhí)坠?jié)字對象和釋放套節(jié)字對象的函數(shù)
PSOCKET_OBJ GetSocketObj(SOCKET s)
{
	PSOCKET_OBJ pSocket = (PSOCKET_OBJ)::GlobalAlloc(GPTR, sizeof(SOCKET_OBJ));
	if(pSocket != NULL)
	{
		pSocket->s = s;
	}
	return pSocket;
}
void FreeSocketObj(PSOCKET_OBJ pSocket)
{
	if(pSocket->s != INVALID_SOCKET)
		::closesocket(pSocket->s);
	::GlobalFree(pSocket);
}

PBUFFER_OBJ GetBufferObj(PSOCKET_OBJ pSocket, ULONG nLen)
{
	if(g_nBufferCount > WSA_MAXIMUM_WAIT_EVENTS - 1)
		return NULL;

	PBUFFER_OBJ pBuffer = (PBUFFER_OBJ)::GlobalAlloc(GPTR, sizeof(BUFFER_OBJ));
	if(pBuffer != NULL)
	{
		pBuffer->buff = (char*)::GlobalAlloc(GPTR, nLen);
		pBuffer->ol.hEvent = ::WSACreateEvent();
		pBuffer->pSocket = pSocket;
		pBuffer->sAccept = INVALID_SOCKET;

		// 將新的BUFFER_OBJ添加到列表中
		if(g_pBufferHead == NULL)
		{
			g_pBufferHead = g_pBufferTail = pBuffer;
		}
		else
		{
			g_pBufferTail->pNext = pBuffer;
			g_pBufferTail = pBuffer;
		}
		g_events[++ g_nBufferCount] = pBuffer->ol.hEvent;
	}
	return pBuffer;
}

void FreeBufferObj(PBUFFER_OBJ pBuffer)
{
	// 從列表中移除BUFFER_OBJ對象
	PBUFFER_OBJ pTest = g_pBufferHead;
	BOOL bFind = FALSE;
	if(pTest == pBuffer)
	{
		g_pBufferHead = g_pBufferTail = NULL;
		bFind = TRUE;
	}
	else
	{
		while(pTest != NULL && pTest->pNext != pBuffer)
			pTest = pTest->pNext;
		if(pTest != NULL)
		{
			pTest->pNext = pBuffer->pNext;
			if(pTest->pNext == NULL)
				g_pBufferTail = pTest;
			bFind = TRUE;
		}
	}
	// 釋放它占用的內(nèi)存空間
	if(bFind)
	{
		g_nBufferCount --;
		::CloseHandle(pBuffer->ol.hEvent);
		::GlobalFree(pBuffer->buff);
		::GlobalFree(pBuffer);	
	}
}

PBUFFER_OBJ FindBufferObj(HANDLE hEvent)
{
	PBUFFER_OBJ pBuffer = g_pBufferHead;
	while(pBuffer != NULL)
	{
		if(pBuffer->ol.hEvent == hEvent)
			break;
		pBuffer = pBuffer->pNext;
	}
	return pBuffer;
}

void RebuildArray()
{
	PBUFFER_OBJ pBuffer = g_pBufferHead;
	int i =  1;
	while(pBuffer != NULL)
	{
		g_events[i++] = pBuffer->ol.hEvent;
		pBuffer = pBuffer->pNext;
	}
}

BOOL PostAccept(PBUFFER_OBJ pBuffer)
{
	PSOCKET_OBJ pSocket = pBuffer->pSocket;
	if(pSocket->lpfnAcceptEx != NULL)
	{	
		// 設(shè)置I/O類型,增加套節(jié)字上的重疊I/O計數(shù)
		pBuffer->nOperation = OP_ACCEPT;
		pSocket->nOutstandingOps ++;

		// 投遞此重疊I/O  
		DWORD dwBytes;
		pBuffer->sAccept = 
			::WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
		BOOL b = pSocket->lpfnAcceptEx(pSocket->s, 
			pBuffer->sAccept,
			pBuffer->buff, 
			BUFFER_SIZE - ((sizeof(sockaddr_in) + 16) * 2),
			sizeof(sockaddr_in) + 16, 
			sizeof(sockaddr_in) + 16, 
			&dwBytes, 
			&pBuffer->ol);
		if(!b)
		{
			if(::WSAGetLastError() != WSA_IO_PENDING)
				return FALSE;
		}
		return TRUE;
	}
	return FALSE;
};

BOOL PostRecv(PBUFFER_OBJ pBuffer)
{	
	// 設(shè)置I/O類型,增加套節(jié)字上的重疊I/O計數(shù)
	pBuffer->nOperation = OP_READ;
	pBuffer->pSocket->nOutstandingOps ++;

	// 投遞此重疊I/O
	DWORD dwBytes;
	DWORD dwFlags = 0;
	WSABUF buf;
	buf.buf = pBuffer->buff;
	buf.len = pBuffer->nLen;
	if(::WSARecv(pBuffer->pSocket->s, &buf, 1, &dwBytes, &dwFlags, &pBuffer->ol, NULL) != NO_ERROR)
	{
		if(::WSAGetLastError() != WSA_IO_PENDING)
			return FALSE;
	}
	return TRUE;
}

BOOL PostSend(PBUFFER_OBJ pBuffer)
{
	// 設(shè)置I/O類型,增加套節(jié)字上的重疊I/O計數(shù)
	pBuffer->nOperation = OP_WRITE;
	pBuffer->pSocket->nOutstandingOps ++;

	// 投遞此重疊I/O
	DWORD dwBytes;
	DWORD dwFlags = 0;
	WSABUF buf;
	buf.buf = pBuffer->buff;
	buf.len = pBuffer->nLen;
	if(::WSASend(pBuffer->pSocket->s, 
			&buf, 1, &dwBytes, dwFlags, &pBuffer->ol, NULL) != NO_ERROR)
	{
		if(::WSAGetLastError() != WSA_IO_PENDING)
			return FALSE;
	}
	return TRUE;
}

BOOL HandleIO(PBUFFER_OBJ pBuffer)
{
	PSOCKET_OBJ pSocket = pBuffer->pSocket; // 從BUFFER_OBJ對象中提取SOCKET_OBJ對象指針,為的是方便引用
	pSocket->nOutstandingOps --;

	// 獲取重疊操作結(jié)果
	DWORD dwTrans;
	DWORD dwFlags;
	BOOL bRet = ::WSAGetOverlappedResult(pSocket->s, &pBuffer->ol, &dwTrans, FALSE, &dwFlags);
	if(!bRet)
	{
		// 在此套節(jié)字上有錯誤發(fā)生,因此,關(guān)閉套節(jié)字,移除此緩沖區(qū)對象。
		// 如果沒有其它拋出的I/O請求了,釋放此緩沖區(qū)對象,否則,等待此套節(jié)字上的其它I/O也完成
		if(pSocket->s != INVALID_SOCKET)
		{
			::closesocket(pSocket->s);
			pSocket->s = INVALID_SOCKET;
		}

		if(pSocket->nOutstandingOps == 0)
			FreeSocketObj(pSocket);	
		
		FreeBufferObj(pBuffer);
		return FALSE;
	}

	// 沒有錯誤發(fā)生,處理已完成的I/O
	switch(pBuffer->nOperation)
	{
	case OP_ACCEPT:	// 接收到一個新的連接,并接收到了對方發(fā)來的第一個封包
		{
			// 為新客戶創(chuàng)建一個SOCKET_OBJ對象
			PSOCKET_OBJ pClient = GetSocketObj(pBuffer->sAccept);

			// 為發(fā)送數(shù)據(jù)創(chuàng)建一個BUFFER_OBJ對象,這個對象會在套節(jié)字出錯或者關(guān)閉時釋放
			PBUFFER_OBJ pSend = GetBufferObj(pClient, BUFFER_SIZE);	
			if(pSend == NULL)
			{
				printf(" Too much connections! \n");
				FreeSocketObj(pClient);
				return FALSE;
			}
			RebuildArray();
			
			// 將數(shù)據(jù)復(fù)制到發(fā)送緩沖區(qū)
			pSend->nLen = dwTrans;
			memcpy(pSend->buff, pBuffer->buff, dwTrans);

			// 投遞此發(fā)送I/O(將數(shù)據(jù)回顯給客戶)
			if(!PostSend(pSend))
			{
				// 萬一出錯的話,釋放上面剛申請的兩個對象
				FreeSocketObj(pSocket);	
				FreeBufferObj(pSend);
				return FALSE;
			}
			// 繼續(xù)投遞接受I/O
			PostAccept(pBuffer);
		}
		break;
	case OP_READ:	// 接收數(shù)據(jù)完成
		{
			if(dwTrans > 0)
			{
				// 創(chuàng)建一個緩沖區(qū),以發(fā)送數(shù)據(jù)。這里就使用原來的緩沖區(qū)
				PBUFFER_OBJ pSend = pBuffer;
				pSend->nLen = dwTrans;
				
				// 投遞發(fā)送I/O(將數(shù)據(jù)回顯給客戶)
				PostSend(pSend);
			}
			else	// 套節(jié)字關(guān)閉
			{
	
				// 必須先關(guān)閉套節(jié)字,以便在此套節(jié)字上投遞的其它I/O也返回
				if(pSocket->s != INVALID_SOCKET)
				{
					::closesocket(pSocket->s);
					pSocket->s = INVALID_SOCKET;
				}

				if(pSocket->nOutstandingOps == 0)
					FreeSocketObj(pSocket);		
				
				FreeBufferObj(pBuffer);
				return FALSE;
			}
		}
		break;
	case OP_WRITE:		// 發(fā)送數(shù)據(jù)完成
		{
			if(dwTrans > 0)
			{
				// 繼續(xù)使用這個緩沖區(qū)投遞接收數(shù)據(jù)的請求
				pBuffer->nLen = BUFFER_SIZE;
				PostRecv(pBuffer);
			}
			else	// 套節(jié)字關(guān)閉
			{
				// 同樣,要先關(guān)閉套節(jié)字
				if(pSocket->s != INVALID_SOCKET)
				{
					::closesocket(pSocket->s);
					pSocket->s = INVALID_SOCKET;
				}

				if(pSocket->nOutstandingOps == 0)
					FreeSocketObj(pSocket);	

				FreeBufferObj(pBuffer);
				return FALSE;
			}
		}
		break;
	}
	return TRUE;
}


void main()
{
	// 創(chuàng)建監(jiān)聽套節(jié)字,綁定到本地端口,進(jìn)入監(jiān)聽模式
	int nPort = 4567;
	SOCKET sListen = 
		::WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
	SOCKADDR_IN si;
	si.sin_family = AF_INET;
	si.sin_port = ::ntohs(nPort);
	si.sin_addr.S_un.S_addr = INADDR_ANY;
	::bind(sListen, (sockaddr*)&si, sizeof(si));
	::listen(sListen, 200);

	// 為監(jiān)聽套節(jié)字創(chuàng)建一個SOCKET_OBJ對象
	PSOCKET_OBJ pListen = GetSocketObj(sListen);

	// 加載擴(kuò)展函數(shù)AcceptEx
	GUID GuidAcceptEx = WSAID_ACCEPTEX;
	DWORD dwBytes;
	WSAIoctl(pListen->s, 
		SIO_GET_EXTENSION_FUNCTION_POINTER, 
		&GuidAcceptEx, 
		sizeof(GuidAcceptEx),
		&pListen->lpfnAcceptEx, 
		sizeof(pListen->lpfnAcceptEx), 
		&dwBytes, 
		NULL, 
		NULL);

	// 創(chuàng)建用來重新建立g_events數(shù)組的事件對象
	g_events[0] = ::WSACreateEvent();

	// 在此可以投遞多個接受I/O請求
	for(int i=0; i<5; i++)
	{
		PostAccept(GetBufferObj(pListen, BUFFER_SIZE));
	}
	::WSASetEvent(g_events[0]);
	
	while(TRUE)
	{
		int nIndex = 
			::WSAWaitForMultipleEvents(g_nBufferCount + 1, g_events, FALSE, WSA_INFINITE, FALSE);
		if(nIndex == WSA_WAIT_FAILED)
		{
			printf("WSAWaitForMultipleEvents() failed \n");
			break;
		}
		nIndex = nIndex - WSA_WAIT_EVENT_0;
		for(int i=0; i<=nIndex; i++)
		{
			int nRet = ::WSAWaitForMultipleEvents(1, &g_events[i], TRUE, 0, FALSE);
			if(nRet == WSA_WAIT_TIMEOUT)
				continue;
			else
			{
				::WSAResetEvent(g_events[i]);
				// 重新建立g_events數(shù)組
				if(i == 0)
				{
					RebuildArray();
					continue;
				}

				// 處理這個I/O
				PBUFFER_OBJ pBuffer = FindBufferObj(g_events[i]);
				if(pBuffer != NULL)
				{
					if(!HandleIO(pBuffer))
						RebuildArray();
				}
			}
		}
	}
}

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
在线中文字幕不卡| 亚洲成国产人片在线观看| 亚洲欧美综合另类在线卡通| 视频一区二区三区中文字幕| jvid福利写真一区二区三区| 欧美大胆一级视频| 成人免费高清视频| 久久影院视频免费| 久久机这里只有精品| 欧美日本韩国一区二区三区视频 | 不卡的av在线播放| 中文字幕av一区二区三区免费看 | 97久久精品人人做人人爽| 中文字幕一区二区三区不卡 | 中文字幕高清不卡| 精品国产一区二区三区不卡| 国产成人综合视频| 亚洲天堂久久久久久久| 色吧成人激情小说| 99视频有精品| 国产精品综合一区二区| 亚洲图片你懂的| 国产精品美日韩| 在线免费精品视频| 天天色天天爱天天射综合| 精品久久一区二区| 国产精品18久久久久| 日本免费新一区视频| 久久久久久久久久久电影| 91麻豆国产自产在线观看| 一区二区三区在线免费观看| 欧美亚一区二区| 狠狠色丁香婷婷综合| 日韩毛片一二三区| 欧美国产乱子伦| 国产免费观看久久| 欧美伦理电影网| 狠狠色丁香久久婷婷综合_中| 奇米四色…亚洲| 欧美经典一区二区三区| 久久精品水蜜桃av综合天堂| 色www精品视频在线观看| 91香蕉视频污在线| 91欧美一区二区| 91麻豆.com| 欧美午夜片在线看| 欧美日韩不卡一区| 777午夜精品视频在线播放| 国产99久久久国产精品免费看| 亚洲欧美日韩国产中文在线| 欧美大白屁股肥臀xxxxxx| 日韩欧美国产综合在线一区二区三区| 欧美一级欧美一级在线播放| 99久久婷婷国产精品综合| 91老师片黄在线观看| 欧美一a一片一级一片| 欧美一区永久视频免费观看| 精品久久久久久无| 国产精品伦理一区二区| 亚洲精品日日夜夜| 国产精品久久久久影院老司| 精品国产免费人成在线观看| 久久理论电影网| 国产精品午夜电影| 亚洲成人1区2区| 黑人巨大精品欧美一区| 99精品久久久久久| 欧美妇女性影城| 国产亚洲短视频| 一区二区三区成人| 久久er99热精品一区二区| 粉嫩av一区二区三区| 在线观看视频91| 2023国产精品自拍| 亚洲色图视频网站| 奇米综合一区二区三区精品视频| 国产成人在线视频播放| 色视频欧美一区二区三区| 高清国产一区二区| 欧美性色黄大片| 久久久久久久久久久电影| 亚洲精品国产无天堂网2021| 久久99久久99| 国内精品伊人久久久久av影院 | 欧美一级片在线观看| 国产欧美久久久精品影院| 亚洲五码中文字幕| 亚洲福利一区二区| 国产成人夜色高潮福利影视| 色天天综合久久久久综合片| 欧美v日韩v国产v| 亚洲一区二区三区中文字幕在线| 亚洲另类一区二区| 极品少妇xxxx精品少妇偷拍 | 色av一区二区| 国产亚洲一区二区三区四区| 亚洲成人自拍一区| 成人小视频在线| 欧美不卡视频一区| 亚洲国产色一区| 99久久综合国产精品| 日韩精品一区在线观看| 香蕉成人啪国产精品视频综合网| 国产91精品在线观看| 欧美电影免费提供在线观看| 亚洲一区二区三区视频在线播放| 国产黄色成人av| 欧美成人a视频| 婷婷成人综合网| 欧美日韩免费视频| 日韩欧美国产高清| 亚洲一区二区三区四区的| 成人听书哪个软件好| 久久精品一区蜜桃臀影院| 日本一道高清亚洲日美韩| 欧美在线视频你懂得| 成人欧美一区二区三区白人| 国产麻豆精品在线| 99国产欧美久久久精品| 国产女人18水真多18精品一级做| 美女视频网站久久| 99麻豆久久久国产精品免费优播| 2020国产精品| 国产一区二区三区电影在线观看| 日韩亚洲欧美一区二区三区| 国产免费观看久久| 国产精品自在在线| 精品国产伦一区二区三区观看方式| 婷婷中文字幕综合| 欧美午夜精品久久久久久超碰| 一区二区在线观看av| 色婷婷亚洲精品| 亚洲欧美日韩小说| 在线观看亚洲专区| 亚洲国产精品久久不卡毛片| 欧美午夜电影在线播放| 偷拍一区二区三区| 91精品国产综合久久久蜜臀图片| 婷婷综合久久一区二区三区| 在线成人高清不卡| 首页欧美精品中文字幕| 91精品欧美久久久久久动漫| 美女性感视频久久| 久久久久久久久久看片| 成人午夜激情片| 亚洲女爱视频在线| 欧美电影一区二区三区| 久久国产精品无码网站| 国产亚洲精品aa| 91在线观看高清| 五月激情综合婷婷| 日韩精品一区二区三区四区视频| 国产一区福利在线| 中文字幕欧美国产| 在线欧美日韩精品| 美日韩黄色大片| 欧美国产综合一区二区| 色综合天天在线| 久久精品欧美一区二区三区不卡 | 欧美日韩国产精品成人| 久久精品国产澳门| 欧美国产精品v| 91极品美女在线| 免费成人在线影院| 国产精品乱码久久久久久| 色哟哟欧美精品| 免费精品视频最新在线| 国产精品少妇自拍| 欧美日韩国产天堂| 国产精品一级黄| 亚洲电影欧美电影有声小说| 久久久国际精品| 在线观看日韩高清av| 国产一区二区三区四区五区美女| 国产精品另类一区| 欧美一区二区成人6969| 成人免费不卡视频| 日本中文字幕一区| 国产精品理论片在线观看| 制服丝袜日韩国产| 99久久精品国产导航| 蜜臀av一区二区在线免费观看| 亚洲国产精品二十页| 欧美日本视频在线| av电影一区二区| 蜜桃视频在线观看一区| 18成人在线视频| 日韩无一区二区| 色狠狠桃花综合| 国产成人超碰人人澡人人澡| 日日摸夜夜添夜夜添国产精品| 欧美激情资源网| 欧美电影免费观看高清完整版| 91网站视频在线观看| 精品一区二区日韩| 亚洲成人自拍网| 亚洲日本一区二区三区| 国产三级一区二区三区| 欧美精品久久一区二区三区| www..com久久爱|