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

📄 serversocket.cpp

📁 几个关于网络模型的代码!有事件选择模型、重叠I/0模型
💻 CPP
字号:
#include "StdAfx.h"
#include ".\serversocket.h"

#define DATA_BUFSIZE 4096

CWinThread* pServerListenThread = NULL;

SOCKET sockListen,sockAccept;

SOCKET sockAcceptArray[WSA_MAXIMUM_WAIT_EVENTS]; // 与客户端通信的SOCKET

WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS],NewEvent;    // 与socket配套的事件组

DWORD EventTotal = 0;
DWORD Index,i;

WSANETWORKEVENTS  NetworkEvents;

// 监听线程
UINT _ServerListenThread(LPVOID lParam)
{
		TRACE("开始监听!");

	while(TRUE)
	{
		TRACE("\n进入循环!");

		Index = WSAWaitForMultipleEvents(EventTotal,EventArray,FALSE,WSA_INFINITE,FALSE);

		Index = Index - WSA_WAIT_EVENT_0;

		for(i = Index;i < EventTotal;i++)
		{
			Index = WSAWaitForMultipleEvents(1,&EventArray[i],TRUE,1000,FALSE);

			if((Index == WSA_WAIT_FAILED) || (Index == WSA_WAIT_TIMEOUT))
				continue;
			else
			{
				Index = i;

				WSAEnumNetworkEvents(sockAcceptArray[Index], EventArray[Index],&NetworkEvents);

				if(NetworkEvents.lNetworkEvents & FD_ACCEPT)
				{
					if(NetworkEvents.iErrorCode[FD_ACCEPT_BIT] != 0)
					{
						AfxMessageBox("accept error!");

						return -1;
					}

					sockAccept = accept(sockAcceptArray[Index],NULL,NULL);

					NewEvent = WSACreateEvent();

					WSAEventSelect(sockAccept,NewEvent,FD_READ | FD_CLOSE);

					EventArray[EventTotal] = NewEvent;
					sockAcceptArray[EventTotal] = sockAccept;

					EventTotal ++;

					TRACE("连接成功!%d\n",sockAccept);


				}

				if(NetworkEvents.lNetworkEvents & FD_READ)
				{
					if(NetworkEvents.iErrorCode[FD_READ_BIT] != 0)
					{
						AfxMessageBox("Read error!");

						return -1;
					}

					char buffer[DATA_BUFSIZE];

					recv(sockAcceptArray[Index - WSA_WAIT_EVENT_0],buffer,sizeof(buffer),0);
					
					TRACE(buffer);
				}

				if(NetworkEvents.lNetworkEvents & FD_CLOSE)
				{
					if(NetworkEvents.iErrorCode[FD_CLOSE_BIT] != 0)
					{
						AfxMessageBox("close error!");

						return -1;
					}
					closesocket(sockAcceptArray[Index]);

					TRACE("\nclose!");

					WSACloseEvent(EventArray[Index - WSA_WAIT_EVENT_0]);

					EventTotal--;
				}

			}
		}
	}

	return 0;
}


CServerSocket::CServerSocket(void)
{
	//for(int i=0;i<WSA_MAXIMUM_WAIT_EVENTS;i++)   // 初始化SOCKET
	//{
	//	sockAcceptArray[i] = INVALID_SOCKET;
	//}
}

CServerSocket::~CServerSocket(void)
{
	TRACE("CServerSocket 析构!");

	if(pServerListenThread != NULL)
	{
		DWORD   dwStatus;
		::GetExitCodeThread(pServerListenThread->m_hThread, &dwStatus);

		if (dwStatus == STILL_ACTIVE)
		{
			delete pServerListenThread;
			pServerListenThread = NULL;
		}
	}

	WSACleanup();
}

// 这些都是固定套路了,没有区别
int CServerSocket::StartListening(const UINT& port)
{
	m_nPort = 11111;

	WSADATA wsaData;

	int nRet;

	nRet=WSAStartup(MAKEWORD(2,2),&wsaData);                      //开启winsock.dll
	if(nRet!=0)
	{
		AfxMessageBox("Load winsock2 failed");
		WSACleanup();
		return -1;
	}

	sockListen = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);         //创建服务套接字(流式)

	SOCKADDR_IN ServerAddr;                                       //分配端口及协议族并绑定

	ServerAddr.sin_family=AF_INET;                                
	ServerAddr.sin_addr.S_un.S_addr  =htonl(INADDR_ANY);          
	ServerAddr.sin_port=htons(port);

	nRet=bind(sockListen,(LPSOCKADDR)&ServerAddr,sizeof(ServerAddr)); // 绑定套接字

	if(nRet==SOCKET_ERROR)
	{
		AfxMessageBox("Bind Socket Fail!");
		closesocket(sockListen);
		return -1;
	}

	NewEvent = WSACreateEvent();

	WSAEventSelect(sockListen,NewEvent,FD_ACCEPT | FD_CLOSE);

	nRet=listen(sockListen,5);                                   //开始监听,并设置监听客户端数量
	if(nRet==SOCKET_ERROR)     
	{
		AfxMessageBox("Listening Fail!");
		return -1;
	}

	sockAcceptArray[EventTotal] = sockListen;
	EventArray[EventTotal] = NewEvent;


    EventTotal++;

	pServerListenThread =  AfxBeginThread(_ServerListenThread,this);    // 开始监听线程

	return 0;
}

int CServerSocket::StopListening()
{
//	bOverlapped = FALSE;

	return 0;
}

// 获得本机IP
CString CServerSocket::GetLocalIP()
{
	WSADATA wsaData;
	if(WSAStartup(MAKEWORD(2,2),&wsaData)==SOCKET_ERROR)
	{
		AfxMessageBox("取得主机名字失败!");
		return "未能获得";
	}

	int nLen=20;
	char hostname[20];
	gethostname(hostname,nLen);        // 获得本机主机名

	CString strHostName(hostname);

	struct hostent FAR* lpHostEnt = gethostbyname(strHostName);

	if(lpHostEnt == NULL)
	{
		return "0.0.0.0";
	}

	LPSTR lpAddr = lpHostEnt->h_addr_list[0];  // 取得IP地址列表中的第一个为返回的IP

	struct in_addr inAddr;

	memmove(&inAddr,lpAddr,4);

	return inet_ntoa(inAddr);         // 转化成标准的IP地址形式
}

⌨️ 快捷键说明

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