#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32")
#pragma warning(disable: 4312)
DWORD WINAPI ServerWorkerThread(LPVOID lpParameter);
#define IOSend 1000
#define IORecv 2000
struct TCPHANDLE
{
SOCKET Sousockid;
SOCKET Desockid;
};
struct IODATA
{
struct
{
WSAOVERLAPPED Overlapped;
DWORD Operation;
WSABUF buf;
char databuf[1024];
}Sou;
struct
{
WSAOVERLAPPED Overlapped;
DWORD Operation;
WSABUF buf;
char databuf[1024];
}De;
};
void main()
{
WSADATA wsaData;
WSAStartup(0x202,&wsaData);
HANDLE CompetionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
SYSTEM_INFO SystenInfo;
GetSystemInfo(&SystenInfo);
for(int i=0;i<SystenInfo.dwNumberOfProcessors*2;i++)
{
CloseHandle(CreateThread(NULL,0,ServerWorkerThread,CompetionPort,0,NULL));
}
SOCKET Listen = socket(AF_INET,SOCK_STREAM,0);
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = INADDR_ANY;
addr.sin_port = htons(1080);
bind(Listen,(sockaddr*)&addr,sizeof(addr));
listen(Listen,5);
TCPHANDLE *tcphandle;
IODATA *iodata;
DWORD Flags;
DWORD RecvBytes;
while(TRUE)
{
SOCKET Accept = accept(Listen,NULL,NULL);
tcphandle = (TCPHANDLE *)GlobalAlloc(GPTR,sizeof(TCPHANDLE));
tcphandle->Sousockid = Accept;
CreateIoCompletionPort((HANDLE)Accept,CompetionPort,(DWORD)tcphandle,0);
iodata = (IODATA *)GlobalAlloc(GPTR,sizeof(IODATA));
iodata->Sou.buf.buf = iodata->Sou.databuf;
iodata->Sou.buf.len = sizeof(iodata->Sou.databuf);
iodata->Sou.Operation = IORecv;
Flags = 0;
WSARecv(tcphandle->Sousockid,&iodata->Sou.buf,1,&RecvBytes,&Flags,&iodata->Sou.Overlapped,NULL);
}
}
DWORD WINAPI ServerWorkerThread(LPVOID lpParameter)
{
DWORD BytesTransferred;
DWORD SendBytes;
DWORD RecvBytes;
DWORD Flags;
DWORD Handle;
IODATA *iodata;
TCPHANDLE *tcphandle;
while(TRUE)
{
GetQueuedCompletionStatus((HANDLE)lpParameter,&BytesTransferred,&Handle,(LPOVERLAPPED*)&iodata,INFINITE);
if (BytesTransferred == 0)
{
closesocket(((TCPHANDLE*)Handle)->Sousockid);;
GlobalFree((HGLOBAL)Handle);
GlobalFree(iodata);
continue;
}
int SockType;
int SockTypelen = sizeof(SockType);
getsockopt(((TCPHANDLE*)Handle)->Sousockid,SOL_SOCKET,SO_TYPE,(char*)&SockType,&SockTypelen);
switch(SockType)
{
case SOCK_STREAM:
{
switch(iodata->Sou.Operation)
{
case IOSend:
{
if (iodata->Sou.buf.len - BytesTransferred != 0)
{
ZeroMemory(&iodata->Sou.Overlapped,sizeof(iodata->Sou.Overlapped));
iodata->Sou.buf.buf += BytesTransferred;
iodata->Sou.buf.len -= BytesTransferred;
if (SOCKET_ERROR == WSASend(((TCPHANDLE*)Handle)->Sousockid,&iodata->Sou.buf,1,&SendBytes,0,&iodata->Sou.Overlapped,NULL))
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
closesocket(((TCPHANDLE*)Handle)->Sousockid);
GlobalFree((HGLOBAL)Handle);
GlobalFree(iodata);
continue;
}
}
}
break;
}
case IORecv:
{
ZeroMemory(&iodata->Sou.Overlapped,sizeof(iodata->Sou.Overlapped));
ZeroMemory(&iodata->De.Overlapped,sizeof(iodata->De.Overlapped));
if (iodata->Sou.databuf[0] == 5 && iodata->Sou.databuf[1] == 1 && iodata->Sou.databuf[2] == 0 && BytesTransferred == 3)
{
iodata->De.databuf[0] = 5;
iodata->De.databuf[1] = 0;
iodata->De.buf.buf = iodata->De.databuf;
iodata->De.buf.len = 2;
iodata->De.Operation = IOSend;
if (SOCKET_ERROR == WSASend(((TCPHANDLE*)Handle)->Sousockid,&iodata->De.buf,1,&SendBytes,0,&iodata->De.Overlapped,NULL))
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
closesocket(((TCPHANDLE*)Handle)->Sousockid);
GlobalFree((HGLOBAL)Handle);
GlobalFree(iodata);
continue;
}
}
}
else if (iodata->Sou.databuf[0] == 5 && iodata->Sou.databuf[1] == 1 && iodata->Sou.databuf[2] == 0 && iodata->Sou.databuf[3] == 1)
{
tcphandle = (TCPHANDLE *)GlobalAlloc(GPTR,sizeof(TCPHANDLE));
tcphandle->Sousockid = socket(AF_INET,SOCK_STREAM,0);
tcphandle->Desockid = ((TCPHANDLE*)Handle)->Sousockid;
((TCPHANDLE*)Handle)->Desockid = tcphandle->Sousockid;
sockaddr_in addr;
addr.sin_family = AF_INET;
CopyMemory(&addr.sin_addr,&iodata->Sou.databuf[4],4);
CopyMemory(&addr.sin_port,&iodata->Sou.databuf[8],2);
bind(tcphandle->Sousockid,(sockaddr*)&addr,sizeof(addr));
DWORD time = GetTickCount();
if (SOCKET_ERROR == connect(tcphandle->Sousockid,(sockaddr*)&addr,sizeof(addr)))
{
Sleep(1);
}
if (GetTickCount()-time > 1000)
{
printf("连接耗时%d毫秒\n",GetTickCount()-time);
}
if (NULL == CreateIoCompletionPort((HANDLE)tcphandle->Sousockid,(HANDLE)lpParameter,(DWORD)tcphandle,0))
{
Sleep(1);
}
IODATA *otheriodata = (IODATA *)GlobalAlloc(GPTR,sizeof(IODATA));
otheriodata->Sou.buf.buf = otheriodata->Sou.databuf;
otheriodata->Sou.buf.len = sizeof(otheriodata->Sou.databuf);
otheriodata->Sou.Operation = IORecv;
Flags = 0;
if (SOCKET_ERROR == WSARecv(tcphandle->Sousockid,&otheriodata->Sou.buf,1,&RecvBytes,&Flags,&otheriodata->Sou.Overlapped,NULL))
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
closesocket(tcphandle->Sousockid);
GlobalFree(tcphandle);
GlobalFree(otheriodata);
continue;
}
}
iodata->De.databuf[0] = 5;
iodata->De.databuf[1] = 0;
iodata->De.databuf[2] = 0;
iodata->De.databuf[3] = 1;
sockaddr_in localaddr;
int localaddrlen = sizeof(localaddr);
getsockname(((TCPHANDLE*)Handle)->Sousockid,(sockaddr*)&localaddr,&localaddrlen);
CopyMemory(&iodata->De.databuf[4],&localaddr.sin_addr,4);
CopyMemory(&iodata->De.databuf[8],&localaddr.sin_port,2);
iodata->De.buf.buf = iodata->De.databuf;
iodata->De.buf.len = 10;
iodata->De.Operation = IOSend;
if(SOCKET_ERROR == WSASend(((TCPHANDLE*)Handle)->Sousockid,&iodata->De.buf,1,&SendBytes,0,&iodata->De.Overlapped,NULL))
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
closesocket(((TCPHANDLE*)Handle)->Sousockid);
GlobalFree((HGLOBAL)Handle);
GlobalFree(iodata);
continue;
}
}
}
else
{
CopyMemory(iodata->De.databuf,iodata->Sou.databuf,BytesTransferred);
iodata->De.buf.buf = iodata->De.databuf;
iodata->De.buf.len = BytesTransferred;
iodata->De.Operation = IOSend;
if (SOCKET_ERROR == WSASend(((TCPHANDLE*)Handle)->Desockid,&iodata->De.buf,1,&SendBytes,0,&iodata->De.Overlapped,NULL))
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
DWORD ret = WSAGetLastError(); //10038
closesocket(((TCPHANDLE*)Handle)->Sousockid);
GlobalFree((HGLOBAL)Handle);
GlobalFree(iodata);
continue;
}
}
}
iodata->Sou.buf.buf = iodata->Sou.databuf;
iodata->Sou.buf.len = sizeof(iodata->Sou.databuf);
iodata->Sou.Operation = IORecv;
Flags = 0;
if (SOCKET_ERROR == WSARecv(((TCPHANDLE*)Handle)->Sousockid,&iodata->Sou.buf,1,&RecvBytes,&Flags,&iodata->Sou.Overlapped,NULL))
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
DWORD ret = WSAGetLastError();
closesocket(((TCPHANDLE*)Handle)->Sousockid);
GlobalFree((HGLOBAL)Handle);
GlobalFree(iodata);
continue;
}
}
break;
}
}
break;
}
case SOCK_DGRAM:
{
break;
}
}
}
return 0;
}
程序存在一些小问题~~
希望高手可以指出来~~~
我一直没有检查到哪里有问题~~~~
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!