⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sock.cpp

📁 一个与金融方面有关的问题
💻 CPP
字号:
/*************************************************
网络类的定义
本网络类利用完成端口模型,对网络相关功能进行了封装
为上层提供透明的网络传输
作者:颜永华               
**************************************************/

#include "StdAfx.h"
#include ".\sock.h"
#define MIN_PACKET 8
typedef CTypedPtrList<CPtrList, CConnectInfo*> CMyList;
CMyList ConnectList;
BOOL EndFlag=FALSE;
//(1)fdsjfdskjfds

CSock::CSock(void)
{
}

CSock::~CSock(void)
{
}
/*
	(2)mmm->CreateIOCPWorkerThread(ddd);
	创建完成端口工作线程
	判断什么时候
	启动ServerWorkerThread
	参数nThread为创建线程的个数
*/
INT CSock::CreateIOCPWorkerThread(int nThread)
{	
	DWORD	dwThreadID;

	if(g_hIOCP != INVALID_HANDLE_VALUE)
	{
		SYSTEM_INFO SystemInfo;
		 //1)创建完全端口
		if ((g_hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL)
			return -1;

		GetSystemInfo(&SystemInfo);
		 //根据处理机的个数创建线程/一般一个处理机创建一个工作线程
		for (UINT i = 0; i < SystemInfo.dwNumberOfProcessors * nThread; i++)
		{
			HANDLE ThreadHandle;

			if ((ThreadHandle = CreateThread(NULL, 0, ServerWorkerThread, g_hIOCP, 0, &dwThreadID)) == NULL)
				return -1;
		
			CloseHandle(ThreadHandle);
		}

		return SystemInfo.dwNumberOfProcessors * nThread;
		//系统处理器的个数*线程数
	}

	return -1;
}
/*
	完成端口上的工作线程
	本线程处理接收和发送数据
	以及对数据库的访问,为业务层提供透明的数据
	本线程函数的好坏,直接影响本网络模型的运行效率
*/
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
	DWORD	dwBytesTransferred;
	printf("server Thread\n");
	CConnectInfo* pConnInfo;
	LPOVERLAPPEDEX pOverlapped;
	while (TRUE)
	{
		if(EndFlag==TRUE)//如果结束标志为真 则结束线程
			return 0;
		GetQueuedCompletionStatus((HANDLE)CompletionPortID,
			&dwBytesTransferred,(PULONG_PTR)&pConnInfo,
			(LPOVERLAPPED*)&pOverlapped,WSA_INFINITE);
		if(dwBytesTransferred==0)
		{	//套接字错误
			::GlobalFree(pOverlapped->DataBuf.buf);
			::GlobalFree(pOverlapped);
			//关闭套接字
			closesocket(pConnInfo->sock);
			continue;
		}else if(pOverlapped->nOvFlag==RECV)
		{	//接受操作完成 处理接受到的封包
			pConnInfo->handleRecvPacket(pOverlapped,dwBytesTransferred);
		}else if(pOverlapped->nOvFlag==SEND)
		{	//发送数据完成 清空发送缓冲区
			::GlobalFree(pOverlapped->DataBuf.buf);
			::GlobalFree(pOverlapped);
			
			continue;
		}
	}

	return 0;
}
/*
	创建监听套接字 并植入监听状态
*/
int CSock::InitServerSocket()
{	
	sListen=WSASocketA(AF_INET, SOCK_STREAM, 0,NULL, 0, WSA_FLAG_OVERLAPPED);
	sockaddr_in localaddr;
	localaddr.sin_family=AF_INET;
	localaddr.sin_addr.S_un.S_addr=::inet_addr("192.168.0.136");
	localaddr.sin_port=::htons(8888);
	if(SOCKET_ERROR==(bind(sListen,(sockaddr*)&localaddr,sizeof(localaddr))))
	{
		::MessageBox(NULL,"bind is err","err",0);
		return 0;
	}
	if(SOCKET_ERROR==(listen(sListen,5)))
	{
		::MessageBox(NULL,"listen is err","err",0);
		return 0;
	}
	
	//创建接受连接线程
	DWORD id;
	HANDLE hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)AcceptThread,(LPVOID)this,0,&id);
	CloseHandle(hThread); 

	//创建工作者线程
	CreateIOCPWorkerThread((int)1);

	return 1;
}
/*
	接受连接线程
	参数lpParameter被传递为网络套接字对象
	以方便对对象数据的访问,将接受连接和创建套接字分开到
	不同的线程中,主要是为了不应为在做其他工作而影响到连接进入
*/
DWORD WINAPI AcceptThread(LPVOID lpParameter)
{	
	//参数转换
	CSock *pSock=(CSock*)lpParameter;

	SOCKET SClient;
	sockaddr_in addr;
	int len=sizeof(sockaddr);
	while(1)
	{	
		if(EndFlag==TRUE)
		{
			return 0;
		}
        SClient=::WSAAccept(pSock->sListen,(sockaddr*)&addr,&len,NULL,0);
		if(SClient!=INVALID_SOCKET)
		{
			SendMessage(pSock->hWnd,WM_SOCKET,(WPARAM)0X0101,(LPARAM)&addr);
			CConnectInfo *pConnInfo=new CConnectInfo;
			
			if(pConnInfo)
			{
				pConnInfo->sock=SClient;
				pConnInfo->netaddr=addr;

				//添加对象到连接列表
				//ConnectList.InsertAfter(ConnectList.GetHeadPosition(),pConnInfo);
				//ConnectList.AddTail(pConnInfo);
				printf("%s\n",inet_ntoa(pConnInfo->netaddr.sin_addr));
				//关联到完成端口
				CreateIoCompletionPort((HANDLE)pConnInfo->sock,pSock->g_hIOCP,(ULONG_PTR)pConnInfo,0);
				//发送密钥   
				pConnInfo->sendKey(pConnInfo->Key.SendKey);
				pConnInfo->sendKey(pConnInfo->Key.RecvKey);
								
			}
		}
		//return 0;
	}
	return 0;
}
/*
	关闭某个套接字
	关闭连接,为了管理客户端
*/
void CSock::CloseConnect(CConnectInfo *pConnInfo)
{
	closesocket(pConnInfo->sock);
	//ConnectList.RemoveAt(ConnectList.Find(pConnInfo));
	delete pConnInfo;
}
/*
	结束服务
*/
void CSock::EndServerSocket()
{
	EndFlag=TRUE;
	//Sleep(10);
	//CloseAllConnect();
	CloseHandle(g_hIOCP);

	closesocket(sListen);
	sListen=INVALID_SOCKET;
	//Sleep(10);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -