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

📄 rsthread.cpp

📁 一个网络接收和发送的程序
💻 CPP
字号:
// RSthread.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "RSthread.h"
#include "winsock2.h"
#include <stdio.h>

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }
    return TRUE;
}

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->event[0]=::WSACreateEvent();
		::EnterCriticalSection(&g_cs);
		pThread->pNext=g_pThreadList;
		g_pThreadList=pThread;
		::LeaveCriticalSection(&g_cs);
	}
	return pThread;
}

void FreeThreadObj(PTHREAD_OBJ 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->pNext=pThread->pNext;
	}

	::LeaveCriticalSection(&g_cs);
	::CloseHandle(pThread->event[0]);
	::DeleteCriticalSection(&pThread->cs);
	::GlobalFree(pThread);
}

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_nTotalConnections);
		::InterlockedIncrement(&g_nCurrentConnections);
	}

	return bRet;
}

void RebuildArray(PTHREAD_OBJ pThread)
{
	::EnterCriticalSection(&pThread->cs);
	PSOCKET_OBJ pSocket=pThread->pSockHeader;

	int n=1;
	while(pSocket!=NULL)
	{
		pThread->event[n++]=pSocket->event;
		pSocket=pSocket->pNext;
	}

	::LeaveCriticalSection(&pThread->cs);
}

void AssigToFreeThread(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->event[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->event[0]);
	::InterlockedDecrement(&g_nCurrentConnections);
}

DWORD WINAPI ServerThread(LPVOID lpParam)
{
	PTHREAD_OBJ pThread=(PTHREAD_OBJ)lpParam;
	while(TRUE)
	{
		int nIndex=::WSAWaitForMultipleEvents(pThread->nSocketCount+1,pThread->event,FALSE,WSA_INFINITE,FALSE);

		nIndex=nIndex-WSA_WAIT_EVENT_0;
		for(int i=nIndex;i<pThread->nSocketCount+1;i++)
		{
			nIndex=::WSAWaitForMultipleEvents(1,&pThread->event[i],TRUE,1000,FALSE);
			if(nIndex==WSA_WAIT_FAILED||nIndex==WSA_WAIT_TIMEOUT)
				continue;
			else
			{
				if(i==0)
				{
					RebuildArray(pThread);
					if(pThread->nSocketCount==0)
					{
						FreeThreadObj(pThread);
						return 0;
					}
					::WSAResetEvent(pThread->event[0]);
				}
				else
				{
					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;
}

PSOCKET_OBJ FindSocketObj(PTHREAD_OBJ pThread,int nIndex)
{
	PSOCKET_OBJ pSocket=pThread->pSockHeader;
	while(--nIndex)
	{
		if(pSocket==NULL)
			return NULL;
		pSocket=pSocket->pNext;
	}

	return pSocket;
}

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;
}

extern "C" RSTHREAD_API DWORD StartSocket()
{
	USHORT nPort=2600;
	SOCKET sListen=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(nPort);
	sin.sin_addr.S_un.S_addr=INADDR_ANY;
	if(::bind(sListen,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR)
	{
		printf("Failed bind()\n");
		return -1;
	}

	::listen(sListen,200);
	WSAEVENT event=::WSACreateEvent();
	::WSAEventSelect(sListen,event,FD_ACCEPT|FD_CLOSE);
	::InitializeCriticalSection(&g_cs);

	while(TRUE)
	{
		int nRet=::WaitForSingleObject(event,5*1000);
		if(nRet==WAIT_FAILED)
		{
			printf("Failed WaitForSingleObject() \n");
			break;
		}
		else if(nRet==WSA_WAIT_TIMEOUT)
		{
			printf("\n");
			printf("Total Connections:%d\n",g_nTotalConnections);
			printf("Current Connections:%d\n",g_nCurrentConnections);
			continue;

		}
		else
		{
			::ResetEvent(event);
			while(TRUE)
			{
				sockaddr_in si;
				int nLen=sizeof(si);
				SOCKET sNew=::accept(sListen,(sockaddr*)&si,&nLen);
				if(sNew==SOCKET_ERROR)
					break;
				
			}
		}

		::DeleteCriticalSection(&g_cs);
		return 0;
	}
	return 0;
}

⌨️ 快捷键说明

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