📄 rsthread.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 + -