[下面的框架可能不正确和/或缺失,没有为 wshtcpip.dll 加载符号]
mswsock.dll!_SockSetHandleContext@4() + 0x14d 字节
mswsock.dll!_SockCoreAccept@8() + 0x286 字节
mswsock.dll!_WSPAccept@24() + 0xa3c 字节
ws2_32.dll!71b71024()
ws2_32.dll!71b712c2()
GateServerR.exe!Share::NetWork::CTcpSocket::Accept(unsigned int & socket=0) 行77 C++
GateServerR.exe!Share::NetWork::CTcpServer::AcceptProcess(unsigned long uAcceptConnPerBatch=) 行145 + 0x39 字节 C++
GateServerR.exe!_itoa() + 0x17ba 字节 C++
GateServerR.exe!0042d96f()
kernel32.dll!__SEH_epilog() + 0x1b 字节
其中调用::accept的地方是这样的:
SOCKET sock = ::accept(m_sock, NULL, NULL);
9 个解决方案
#1
重新修改下:
> wshtcpip.dll!_WSHGetSocketInformation@32() + 0x35 字节
mswsock.dll!_SockSetHandleContext@4() + 0x14d 字节
mswsock.dll!_SockCoreAccept@8() + 0x286 字节
mswsock.dll!_WSPAccept@24() + 0xa3c 字节
ws2_32.dll!_WSAAccept@20() + 0x85 字节
ws2_32.dll!_accept@12() + 0x17 字节
GateServerR.exe!Share::NetWork::CTcpSocket::Accept(unsigned int & socket=0) 行77 C++
> wshtcpip.dll!_WSHGetSocketInformation@32() + 0x35 字节
mswsock.dll!_SockSetHandleContext@4() + 0x14d 字节
mswsock.dll!_SockCoreAccept@8() + 0x286 字节
mswsock.dll!_WSPAccept@24() + 0xa3c 字节
ws2_32.dll!_WSAAccept@20() + 0x85 字节
ws2_32.dll!_accept@12() + 0x17 字节
GateServerR.exe!Share::NetWork::CTcpSocket::Accept(unsigned int & socket=0) 行77 C++
#2
???
没看懂
没看懂
#3
没碰到过
#4
出现什么问题?
#5
楼主挺可怜啊,可用分是奴隶
#6
没明白。。。。只能up了!可以google下
#7
没看明白lz说的什么意思
#8
if ((Accept = WSAAccept(Listen, (SOCKADDR*)&ClientAddr, &addr_length, NULL, 0)) == SOCKET_ERROR)
{
printf("WSAAccept() failed with error %d\n", WSAGetLastError());
return 0;
}
我们一般用这个函数来获取..客户端发过的信息,如果与server配对,就生成一个socket号,用于client与server的连接;
参考一下..这个。。。
//server iocmplt
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
HANDLE CompletionPort = (HANDLE) CompletionPortID;
DWORD BytesTransferred;
LPOVERLAPPED Overlapped;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
DWORD SendBytes, RecvBytes;
DWORD Flags;
int i;
while(TRUE)
{
if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE) == 0)
{
printf("GetQueuedCompletionStatus failed with error %d\n", GetLastError());
//MessageBox(SAVE_HWND, "GetQueuedCompletionStatus failed with error", "erroe", MB_OK);
}
// EnterCriticalSection(&CriticalSection);
if (BytesTransferred == 0)
{
printf("断线\n");
printf("Closing socket %d\n", PerHandleData->Socket);
DisposalCut(PerHandleData->Socket);
GlobalFree(PerHandleData);
GlobalFree(PerIoData);
// LeaveCriticalSection(&CriticalSection);
continue;
}
Flags = 0;
RecvBytes=0;
ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
PerIoData->DataBuf.len = 8192000;//DATA_BUFSIZE;
PerIoData->DataBuf.buf = LHxxRecvBuffer;//PerIoData->Buffer;
if(WSARecv(PerHandleData->Socket, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,
&(PerIoData->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed Awith error %d\n", WSAGetLastError());
//MessageBox(SAVE_HWND, "WSARecv", "erroe", MB_OK);
}
}
//recv(PerHandleData->Socket,PerIoData->DataBuf.buf,DATA_BUFSIZE,Flags);
//PerIoData->Buffer[RecvBytes]='\0';
printf("psize:%d\n",BytesTransferred);
/* for(int i=0;i<4;i++)
{
LHxxRecvBuffer[i]^=SPassword[i%4];
LHxxRecvBuffer[i]^=4+83;
}*/
#define PCKNUM 13
int PckName[PCKNUM]=
{
NCD_NONE,
//game scene
F_NCDInOutScene,//上线,下线
F_NCDPlayMove,//人物的移动
//lobby
F_NCDSerHostListId,//服务器列表
F_NCDSaveClickPosition,//click role position
F_NCDMagicAttack,//MAGIC
F_NCDRoleState,//主角状态
F_NCDEnemyMove,//敌人移动
F_NCDSaveEnemyMove, //存放敌人移动后的坐标
F_NCDEnemyState,
F_NCDEnemyPh,
F_NCDArticleUseSell,//物品买卖使用
F_NCDAttackMagicEnemy
};
int PckSize[PCKNUM]=
{
sizeof(NCD_NONE),
sizeof(NCDInOutScene),
sizeof(NCDPlayMove),
sizeof(NCDSerHostListId),
sizeof(NCDSaveClickPosition),
sizeof(NCDMagicAttack),
sizeof(NCDRoleState),
sizeof(NCDEnemyMove),
sizeof(NCDSaveEnemyMove),
sizeof(NCDEnemyState),
sizeof(NCDEnemyPh),
sizeof(NCDArticleUseSell),
sizeof(NCDAttackMagicEnemy)
};
int Pok=LHxxSTARTDISPOSE_PACK(0,BytesTransferred,PCKNUM,PckName,PckSize);
if(Pok==0 || BytesTransferred==0)
{
NCD_HEADERS *pd=(NCD_HEADERS*)LHxxRBufSp;
printf("接收出错 Pok:%d BytesTransferred:%d \n",Pok,BytesTransferred);
printf("接收出错 cmd:%d\n",pd->nCmd);
// MessageBox(SAVE_HWND,"接收出错\n", "readme", MB_OK);
}
if(Pok>0)
{
//BytesTransferred:收到包的总大小; PerIoData->Buffer:包的类型(NCD_HEADERS等)
DisposalPack(LHxxRBufSp,BytesTransferred,PerHandleData->Socket);//disposal 行动pack ;PerHandleData->Socket:服务器SOCKET号
}
LHxxENDDISPOSE_PACK();
//strcpy(PerIoData->Buffer,"");
// LeaveCriticalSection(&CriticalSection);
Sleep(10);
}
}
DWORD WINAPI TCPSERVER_IOCMPLT_PROCESS(LPVOID lpParameter)
{
SOCKADDR_IN InternetAddr;
SOCKET Listen;
SOCKET Accept;
HANDLE CompletionPort;
SYSTEM_INFO SystemInfo;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
int i;
DWORD RecvBytes;
DWORD Flags;
DWORD ThreadID;
DWORD Ret;
// Setup an I/O completion port.
if ((CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL)
{
printf( "CreateIoCompletionPort failed with error: %d\n", GetLastError());
return 0;
}
// Determine how many processors are on the system.
GetSystemInfo(&SystemInfo);
// Create worker threads based on the number of processors available on the
// system. Create two worker threads for each processor.
for(i = 0; i < SystemInfo.dwNumberOfProcessors * 2; i++)
{
HANDLE ThreadHandle;
// Create a server worker thread and pass the completion port to the thread.
if ((ThreadHandle = CreateThread(NULL, 0, ServerWorkerThread, CompletionPort,
0, &ThreadID)) == NULL)
{
printf("CreateThread() failed with error %d\n", GetLastError());
return 0;
}
// Close the thread handle
CloseHandle(ThreadHandle);
}
// Create a listening socket
if ((Listen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,
WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("WSASocket() failed with error %d\n", WSAGetLastError());
return 0;
}
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(ServerPort);
if (bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
{
printf("bind() failed with error %d\n", WSAGetLastError());
return 0;
}
// Prepare socket for listening
if (listen(Listen, 5) == SOCKET_ERROR)
{
printf("listen() failed with error %d\n", WSAGetLastError());
return 0;
}
// Accept connections and assign to the completion port.
int GsStartLink=0;
printf("服务器等待.....\n");
while(TRUE)
{
SOCKADDR_IN ClientAddr; // 定义一个客户端得地址结构作为参数
int addr_length=sizeof(ClientAddr);
if ((Accept = WSAAccept(Listen, (SOCKADDR*)&ClientAddr, &addr_length, NULL, 0)) == SOCKET_ERROR)
{
printf("WSAAccept() failed with error %d\n", WSAGetLastError());
return 0;
}
LPCTSTR lpIP = inet_ntoa(ClientAddr.sin_addr); // IP
UINT nPort = ClientAddr.sin_port; // Port
printf("lpIP:%s nPort:%d sk:%d\n",lpIP,nPort,Accept);
//testing (将数据放入sever list,以便日后发送给client(最主要作用系发送通道号))
AddHostPlayList(Accept,(char*)&Accept);
// Create a socket information structure to associate with the socket
if ((PerHandleData = (LPPER_HANDLE_DATA) GlobalAlloc(GPTR,
sizeof(PER_HANDLE_DATA))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
return 0;
}
// Associate the accepted socket with the original completion port.
PerHandleData->Socket = Accept;
if (CreateIoCompletionPort((HANDLE)Accept, CompletionPort, (DWORD) PerHandleData,
0) == NULL)
{
printf("CreateIoCompletionPort failed with error %d\n", GetLastError());
return 0;
}
// Create per I/O socket information structure to associate with the
// WSARecv call below.
if ((PerIoData = (LPPER_IO_OPERATION_DATA) GlobalAlloc(GPTR, sizeof(PER_IO_OPERATION_DATA))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
return 0;
}
ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
PerIoData->BytesSEND = 0;
PerIoData->BytesRECV = 0;
PerIoData->DataBuf.len = 8192000;//DATA_BUFSIZE;
PerIoData->DataBuf.buf = LHxxRecvBuffer;//PerIoData->Buffer;
Flags = 0;
if (WSARecv(Accept, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,
&(PerIoData->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
//MessageBox(SAVE_HWND, "WSARecv() Accept", "erroe", MB_OK);
}
}
Sleep(10);
}
}
{
printf("WSAAccept() failed with error %d\n", WSAGetLastError());
return 0;
}
我们一般用这个函数来获取..客户端发过的信息,如果与server配对,就生成一个socket号,用于client与server的连接;
参考一下..这个。。。
//server iocmplt
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
HANDLE CompletionPort = (HANDLE) CompletionPortID;
DWORD BytesTransferred;
LPOVERLAPPED Overlapped;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
DWORD SendBytes, RecvBytes;
DWORD Flags;
int i;
while(TRUE)
{
if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE) == 0)
{
printf("GetQueuedCompletionStatus failed with error %d\n", GetLastError());
//MessageBox(SAVE_HWND, "GetQueuedCompletionStatus failed with error", "erroe", MB_OK);
}
// EnterCriticalSection(&CriticalSection);
if (BytesTransferred == 0)
{
printf("断线\n");
printf("Closing socket %d\n", PerHandleData->Socket);
DisposalCut(PerHandleData->Socket);
GlobalFree(PerHandleData);
GlobalFree(PerIoData);
// LeaveCriticalSection(&CriticalSection);
continue;
}
Flags = 0;
RecvBytes=0;
ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
PerIoData->DataBuf.len = 8192000;//DATA_BUFSIZE;
PerIoData->DataBuf.buf = LHxxRecvBuffer;//PerIoData->Buffer;
if(WSARecv(PerHandleData->Socket, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,
&(PerIoData->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed Awith error %d\n", WSAGetLastError());
//MessageBox(SAVE_HWND, "WSARecv", "erroe", MB_OK);
}
}
//recv(PerHandleData->Socket,PerIoData->DataBuf.buf,DATA_BUFSIZE,Flags);
//PerIoData->Buffer[RecvBytes]='\0';
printf("psize:%d\n",BytesTransferred);
/* for(int i=0;i<4;i++)
{
LHxxRecvBuffer[i]^=SPassword[i%4];
LHxxRecvBuffer[i]^=4+83;
}*/
#define PCKNUM 13
int PckName[PCKNUM]=
{
NCD_NONE,
//game scene
F_NCDInOutScene,//上线,下线
F_NCDPlayMove,//人物的移动
//lobby
F_NCDSerHostListId,//服务器列表
F_NCDSaveClickPosition,//click role position
F_NCDMagicAttack,//MAGIC
F_NCDRoleState,//主角状态
F_NCDEnemyMove,//敌人移动
F_NCDSaveEnemyMove, //存放敌人移动后的坐标
F_NCDEnemyState,
F_NCDEnemyPh,
F_NCDArticleUseSell,//物品买卖使用
F_NCDAttackMagicEnemy
};
int PckSize[PCKNUM]=
{
sizeof(NCD_NONE),
sizeof(NCDInOutScene),
sizeof(NCDPlayMove),
sizeof(NCDSerHostListId),
sizeof(NCDSaveClickPosition),
sizeof(NCDMagicAttack),
sizeof(NCDRoleState),
sizeof(NCDEnemyMove),
sizeof(NCDSaveEnemyMove),
sizeof(NCDEnemyState),
sizeof(NCDEnemyPh),
sizeof(NCDArticleUseSell),
sizeof(NCDAttackMagicEnemy)
};
int Pok=LHxxSTARTDISPOSE_PACK(0,BytesTransferred,PCKNUM,PckName,PckSize);
if(Pok==0 || BytesTransferred==0)
{
NCD_HEADERS *pd=(NCD_HEADERS*)LHxxRBufSp;
printf("接收出错 Pok:%d BytesTransferred:%d \n",Pok,BytesTransferred);
printf("接收出错 cmd:%d\n",pd->nCmd);
// MessageBox(SAVE_HWND,"接收出错\n", "readme", MB_OK);
}
if(Pok>0)
{
//BytesTransferred:收到包的总大小; PerIoData->Buffer:包的类型(NCD_HEADERS等)
DisposalPack(LHxxRBufSp,BytesTransferred,PerHandleData->Socket);//disposal 行动pack ;PerHandleData->Socket:服务器SOCKET号
}
LHxxENDDISPOSE_PACK();
//strcpy(PerIoData->Buffer,"");
// LeaveCriticalSection(&CriticalSection);
Sleep(10);
}
}
DWORD WINAPI TCPSERVER_IOCMPLT_PROCESS(LPVOID lpParameter)
{
SOCKADDR_IN InternetAddr;
SOCKET Listen;
SOCKET Accept;
HANDLE CompletionPort;
SYSTEM_INFO SystemInfo;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
int i;
DWORD RecvBytes;
DWORD Flags;
DWORD ThreadID;
DWORD Ret;
// Setup an I/O completion port.
if ((CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL)
{
printf( "CreateIoCompletionPort failed with error: %d\n", GetLastError());
return 0;
}
// Determine how many processors are on the system.
GetSystemInfo(&SystemInfo);
// Create worker threads based on the number of processors available on the
// system. Create two worker threads for each processor.
for(i = 0; i < SystemInfo.dwNumberOfProcessors * 2; i++)
{
HANDLE ThreadHandle;
// Create a server worker thread and pass the completion port to the thread.
if ((ThreadHandle = CreateThread(NULL, 0, ServerWorkerThread, CompletionPort,
0, &ThreadID)) == NULL)
{
printf("CreateThread() failed with error %d\n", GetLastError());
return 0;
}
// Close the thread handle
CloseHandle(ThreadHandle);
}
// Create a listening socket
if ((Listen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,
WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("WSASocket() failed with error %d\n", WSAGetLastError());
return 0;
}
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(ServerPort);
if (bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
{
printf("bind() failed with error %d\n", WSAGetLastError());
return 0;
}
// Prepare socket for listening
if (listen(Listen, 5) == SOCKET_ERROR)
{
printf("listen() failed with error %d\n", WSAGetLastError());
return 0;
}
// Accept connections and assign to the completion port.
int GsStartLink=0;
printf("服务器等待.....\n");
while(TRUE)
{
SOCKADDR_IN ClientAddr; // 定义一个客户端得地址结构作为参数
int addr_length=sizeof(ClientAddr);
if ((Accept = WSAAccept(Listen, (SOCKADDR*)&ClientAddr, &addr_length, NULL, 0)) == SOCKET_ERROR)
{
printf("WSAAccept() failed with error %d\n", WSAGetLastError());
return 0;
}
LPCTSTR lpIP = inet_ntoa(ClientAddr.sin_addr); // IP
UINT nPort = ClientAddr.sin_port; // Port
printf("lpIP:%s nPort:%d sk:%d\n",lpIP,nPort,Accept);
//testing (将数据放入sever list,以便日后发送给client(最主要作用系发送通道号))
AddHostPlayList(Accept,(char*)&Accept);
// Create a socket information structure to associate with the socket
if ((PerHandleData = (LPPER_HANDLE_DATA) GlobalAlloc(GPTR,
sizeof(PER_HANDLE_DATA))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
return 0;
}
// Associate the accepted socket with the original completion port.
PerHandleData->Socket = Accept;
if (CreateIoCompletionPort((HANDLE)Accept, CompletionPort, (DWORD) PerHandleData,
0) == NULL)
{
printf("CreateIoCompletionPort failed with error %d\n", GetLastError());
return 0;
}
// Create per I/O socket information structure to associate with the
// WSARecv call below.
if ((PerIoData = (LPPER_IO_OPERATION_DATA) GlobalAlloc(GPTR, sizeof(PER_IO_OPERATION_DATA))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
return 0;
}
ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
PerIoData->BytesSEND = 0;
PerIoData->BytesRECV = 0;
PerIoData->DataBuf.len = 8192000;//DATA_BUFSIZE;
PerIoData->DataBuf.buf = LHxxRecvBuffer;//PerIoData->Buffer;
Flags = 0;
if (WSARecv(Accept, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,
&(PerIoData->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
//MessageBox(SAVE_HWND, "WSARecv() Accept", "erroe", MB_OK);
}
}
Sleep(10);
}
}
#9
看了半天WIN2K的实现代码还有逆向dll的东西,大概有点思路了。也不知道正确否。
贴子结了再说~
贴子结了再说~
#1
重新修改下:
> wshtcpip.dll!_WSHGetSocketInformation@32() + 0x35 字节
mswsock.dll!_SockSetHandleContext@4() + 0x14d 字节
mswsock.dll!_SockCoreAccept@8() + 0x286 字节
mswsock.dll!_WSPAccept@24() + 0xa3c 字节
ws2_32.dll!_WSAAccept@20() + 0x85 字节
ws2_32.dll!_accept@12() + 0x17 字节
GateServerR.exe!Share::NetWork::CTcpSocket::Accept(unsigned int & socket=0) 行77 C++
> wshtcpip.dll!_WSHGetSocketInformation@32() + 0x35 字节
mswsock.dll!_SockSetHandleContext@4() + 0x14d 字节
mswsock.dll!_SockCoreAccept@8() + 0x286 字节
mswsock.dll!_WSPAccept@24() + 0xa3c 字节
ws2_32.dll!_WSAAccept@20() + 0x85 字节
ws2_32.dll!_accept@12() + 0x17 字节
GateServerR.exe!Share::NetWork::CTcpSocket::Accept(unsigned int & socket=0) 行77 C++
#2
???
没看懂
没看懂
#3
没碰到过
#4
出现什么问题?
#5
楼主挺可怜啊,可用分是奴隶
#6
没明白。。。。只能up了!可以google下
#7
没看明白lz说的什么意思
#8
if ((Accept = WSAAccept(Listen, (SOCKADDR*)&ClientAddr, &addr_length, NULL, 0)) == SOCKET_ERROR)
{
printf("WSAAccept() failed with error %d\n", WSAGetLastError());
return 0;
}
我们一般用这个函数来获取..客户端发过的信息,如果与server配对,就生成一个socket号,用于client与server的连接;
参考一下..这个。。。
//server iocmplt
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
HANDLE CompletionPort = (HANDLE) CompletionPortID;
DWORD BytesTransferred;
LPOVERLAPPED Overlapped;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
DWORD SendBytes, RecvBytes;
DWORD Flags;
int i;
while(TRUE)
{
if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE) == 0)
{
printf("GetQueuedCompletionStatus failed with error %d\n", GetLastError());
//MessageBox(SAVE_HWND, "GetQueuedCompletionStatus failed with error", "erroe", MB_OK);
}
// EnterCriticalSection(&CriticalSection);
if (BytesTransferred == 0)
{
printf("断线\n");
printf("Closing socket %d\n", PerHandleData->Socket);
DisposalCut(PerHandleData->Socket);
GlobalFree(PerHandleData);
GlobalFree(PerIoData);
// LeaveCriticalSection(&CriticalSection);
continue;
}
Flags = 0;
RecvBytes=0;
ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
PerIoData->DataBuf.len = 8192000;//DATA_BUFSIZE;
PerIoData->DataBuf.buf = LHxxRecvBuffer;//PerIoData->Buffer;
if(WSARecv(PerHandleData->Socket, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,
&(PerIoData->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed Awith error %d\n", WSAGetLastError());
//MessageBox(SAVE_HWND, "WSARecv", "erroe", MB_OK);
}
}
//recv(PerHandleData->Socket,PerIoData->DataBuf.buf,DATA_BUFSIZE,Flags);
//PerIoData->Buffer[RecvBytes]='\0';
printf("psize:%d\n",BytesTransferred);
/* for(int i=0;i<4;i++)
{
LHxxRecvBuffer[i]^=SPassword[i%4];
LHxxRecvBuffer[i]^=4+83;
}*/
#define PCKNUM 13
int PckName[PCKNUM]=
{
NCD_NONE,
//game scene
F_NCDInOutScene,//上线,下线
F_NCDPlayMove,//人物的移动
//lobby
F_NCDSerHostListId,//服务器列表
F_NCDSaveClickPosition,//click role position
F_NCDMagicAttack,//MAGIC
F_NCDRoleState,//主角状态
F_NCDEnemyMove,//敌人移动
F_NCDSaveEnemyMove, //存放敌人移动后的坐标
F_NCDEnemyState,
F_NCDEnemyPh,
F_NCDArticleUseSell,//物品买卖使用
F_NCDAttackMagicEnemy
};
int PckSize[PCKNUM]=
{
sizeof(NCD_NONE),
sizeof(NCDInOutScene),
sizeof(NCDPlayMove),
sizeof(NCDSerHostListId),
sizeof(NCDSaveClickPosition),
sizeof(NCDMagicAttack),
sizeof(NCDRoleState),
sizeof(NCDEnemyMove),
sizeof(NCDSaveEnemyMove),
sizeof(NCDEnemyState),
sizeof(NCDEnemyPh),
sizeof(NCDArticleUseSell),
sizeof(NCDAttackMagicEnemy)
};
int Pok=LHxxSTARTDISPOSE_PACK(0,BytesTransferred,PCKNUM,PckName,PckSize);
if(Pok==0 || BytesTransferred==0)
{
NCD_HEADERS *pd=(NCD_HEADERS*)LHxxRBufSp;
printf("接收出错 Pok:%d BytesTransferred:%d \n",Pok,BytesTransferred);
printf("接收出错 cmd:%d\n",pd->nCmd);
// MessageBox(SAVE_HWND,"接收出错\n", "readme", MB_OK);
}
if(Pok>0)
{
//BytesTransferred:收到包的总大小; PerIoData->Buffer:包的类型(NCD_HEADERS等)
DisposalPack(LHxxRBufSp,BytesTransferred,PerHandleData->Socket);//disposal 行动pack ;PerHandleData->Socket:服务器SOCKET号
}
LHxxENDDISPOSE_PACK();
//strcpy(PerIoData->Buffer,"");
// LeaveCriticalSection(&CriticalSection);
Sleep(10);
}
}
DWORD WINAPI TCPSERVER_IOCMPLT_PROCESS(LPVOID lpParameter)
{
SOCKADDR_IN InternetAddr;
SOCKET Listen;
SOCKET Accept;
HANDLE CompletionPort;
SYSTEM_INFO SystemInfo;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
int i;
DWORD RecvBytes;
DWORD Flags;
DWORD ThreadID;
DWORD Ret;
// Setup an I/O completion port.
if ((CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL)
{
printf( "CreateIoCompletionPort failed with error: %d\n", GetLastError());
return 0;
}
// Determine how many processors are on the system.
GetSystemInfo(&SystemInfo);
// Create worker threads based on the number of processors available on the
// system. Create two worker threads for each processor.
for(i = 0; i < SystemInfo.dwNumberOfProcessors * 2; i++)
{
HANDLE ThreadHandle;
// Create a server worker thread and pass the completion port to the thread.
if ((ThreadHandle = CreateThread(NULL, 0, ServerWorkerThread, CompletionPort,
0, &ThreadID)) == NULL)
{
printf("CreateThread() failed with error %d\n", GetLastError());
return 0;
}
// Close the thread handle
CloseHandle(ThreadHandle);
}
// Create a listening socket
if ((Listen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,
WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("WSASocket() failed with error %d\n", WSAGetLastError());
return 0;
}
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(ServerPort);
if (bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
{
printf("bind() failed with error %d\n", WSAGetLastError());
return 0;
}
// Prepare socket for listening
if (listen(Listen, 5) == SOCKET_ERROR)
{
printf("listen() failed with error %d\n", WSAGetLastError());
return 0;
}
// Accept connections and assign to the completion port.
int GsStartLink=0;
printf("服务器等待.....\n");
while(TRUE)
{
SOCKADDR_IN ClientAddr; // 定义一个客户端得地址结构作为参数
int addr_length=sizeof(ClientAddr);
if ((Accept = WSAAccept(Listen, (SOCKADDR*)&ClientAddr, &addr_length, NULL, 0)) == SOCKET_ERROR)
{
printf("WSAAccept() failed with error %d\n", WSAGetLastError());
return 0;
}
LPCTSTR lpIP = inet_ntoa(ClientAddr.sin_addr); // IP
UINT nPort = ClientAddr.sin_port; // Port
printf("lpIP:%s nPort:%d sk:%d\n",lpIP,nPort,Accept);
//testing (将数据放入sever list,以便日后发送给client(最主要作用系发送通道号))
AddHostPlayList(Accept,(char*)&Accept);
// Create a socket information structure to associate with the socket
if ((PerHandleData = (LPPER_HANDLE_DATA) GlobalAlloc(GPTR,
sizeof(PER_HANDLE_DATA))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
return 0;
}
// Associate the accepted socket with the original completion port.
PerHandleData->Socket = Accept;
if (CreateIoCompletionPort((HANDLE)Accept, CompletionPort, (DWORD) PerHandleData,
0) == NULL)
{
printf("CreateIoCompletionPort failed with error %d\n", GetLastError());
return 0;
}
// Create per I/O socket information structure to associate with the
// WSARecv call below.
if ((PerIoData = (LPPER_IO_OPERATION_DATA) GlobalAlloc(GPTR, sizeof(PER_IO_OPERATION_DATA))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
return 0;
}
ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
PerIoData->BytesSEND = 0;
PerIoData->BytesRECV = 0;
PerIoData->DataBuf.len = 8192000;//DATA_BUFSIZE;
PerIoData->DataBuf.buf = LHxxRecvBuffer;//PerIoData->Buffer;
Flags = 0;
if (WSARecv(Accept, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,
&(PerIoData->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
//MessageBox(SAVE_HWND, "WSARecv() Accept", "erroe", MB_OK);
}
}
Sleep(10);
}
}
{
printf("WSAAccept() failed with error %d\n", WSAGetLastError());
return 0;
}
我们一般用这个函数来获取..客户端发过的信息,如果与server配对,就生成一个socket号,用于client与server的连接;
参考一下..这个。。。
//server iocmplt
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
HANDLE CompletionPort = (HANDLE) CompletionPortID;
DWORD BytesTransferred;
LPOVERLAPPED Overlapped;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
DWORD SendBytes, RecvBytes;
DWORD Flags;
int i;
while(TRUE)
{
if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE) == 0)
{
printf("GetQueuedCompletionStatus failed with error %d\n", GetLastError());
//MessageBox(SAVE_HWND, "GetQueuedCompletionStatus failed with error", "erroe", MB_OK);
}
// EnterCriticalSection(&CriticalSection);
if (BytesTransferred == 0)
{
printf("断线\n");
printf("Closing socket %d\n", PerHandleData->Socket);
DisposalCut(PerHandleData->Socket);
GlobalFree(PerHandleData);
GlobalFree(PerIoData);
// LeaveCriticalSection(&CriticalSection);
continue;
}
Flags = 0;
RecvBytes=0;
ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
PerIoData->DataBuf.len = 8192000;//DATA_BUFSIZE;
PerIoData->DataBuf.buf = LHxxRecvBuffer;//PerIoData->Buffer;
if(WSARecv(PerHandleData->Socket, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,
&(PerIoData->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed Awith error %d\n", WSAGetLastError());
//MessageBox(SAVE_HWND, "WSARecv", "erroe", MB_OK);
}
}
//recv(PerHandleData->Socket,PerIoData->DataBuf.buf,DATA_BUFSIZE,Flags);
//PerIoData->Buffer[RecvBytes]='\0';
printf("psize:%d\n",BytesTransferred);
/* for(int i=0;i<4;i++)
{
LHxxRecvBuffer[i]^=SPassword[i%4];
LHxxRecvBuffer[i]^=4+83;
}*/
#define PCKNUM 13
int PckName[PCKNUM]=
{
NCD_NONE,
//game scene
F_NCDInOutScene,//上线,下线
F_NCDPlayMove,//人物的移动
//lobby
F_NCDSerHostListId,//服务器列表
F_NCDSaveClickPosition,//click role position
F_NCDMagicAttack,//MAGIC
F_NCDRoleState,//主角状态
F_NCDEnemyMove,//敌人移动
F_NCDSaveEnemyMove, //存放敌人移动后的坐标
F_NCDEnemyState,
F_NCDEnemyPh,
F_NCDArticleUseSell,//物品买卖使用
F_NCDAttackMagicEnemy
};
int PckSize[PCKNUM]=
{
sizeof(NCD_NONE),
sizeof(NCDInOutScene),
sizeof(NCDPlayMove),
sizeof(NCDSerHostListId),
sizeof(NCDSaveClickPosition),
sizeof(NCDMagicAttack),
sizeof(NCDRoleState),
sizeof(NCDEnemyMove),
sizeof(NCDSaveEnemyMove),
sizeof(NCDEnemyState),
sizeof(NCDEnemyPh),
sizeof(NCDArticleUseSell),
sizeof(NCDAttackMagicEnemy)
};
int Pok=LHxxSTARTDISPOSE_PACK(0,BytesTransferred,PCKNUM,PckName,PckSize);
if(Pok==0 || BytesTransferred==0)
{
NCD_HEADERS *pd=(NCD_HEADERS*)LHxxRBufSp;
printf("接收出错 Pok:%d BytesTransferred:%d \n",Pok,BytesTransferred);
printf("接收出错 cmd:%d\n",pd->nCmd);
// MessageBox(SAVE_HWND,"接收出错\n", "readme", MB_OK);
}
if(Pok>0)
{
//BytesTransferred:收到包的总大小; PerIoData->Buffer:包的类型(NCD_HEADERS等)
DisposalPack(LHxxRBufSp,BytesTransferred,PerHandleData->Socket);//disposal 行动pack ;PerHandleData->Socket:服务器SOCKET号
}
LHxxENDDISPOSE_PACK();
//strcpy(PerIoData->Buffer,"");
// LeaveCriticalSection(&CriticalSection);
Sleep(10);
}
}
DWORD WINAPI TCPSERVER_IOCMPLT_PROCESS(LPVOID lpParameter)
{
SOCKADDR_IN InternetAddr;
SOCKET Listen;
SOCKET Accept;
HANDLE CompletionPort;
SYSTEM_INFO SystemInfo;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
int i;
DWORD RecvBytes;
DWORD Flags;
DWORD ThreadID;
DWORD Ret;
// Setup an I/O completion port.
if ((CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL)
{
printf( "CreateIoCompletionPort failed with error: %d\n", GetLastError());
return 0;
}
// Determine how many processors are on the system.
GetSystemInfo(&SystemInfo);
// Create worker threads based on the number of processors available on the
// system. Create two worker threads for each processor.
for(i = 0; i < SystemInfo.dwNumberOfProcessors * 2; i++)
{
HANDLE ThreadHandle;
// Create a server worker thread and pass the completion port to the thread.
if ((ThreadHandle = CreateThread(NULL, 0, ServerWorkerThread, CompletionPort,
0, &ThreadID)) == NULL)
{
printf("CreateThread() failed with error %d\n", GetLastError());
return 0;
}
// Close the thread handle
CloseHandle(ThreadHandle);
}
// Create a listening socket
if ((Listen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,
WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("WSASocket() failed with error %d\n", WSAGetLastError());
return 0;
}
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(ServerPort);
if (bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
{
printf("bind() failed with error %d\n", WSAGetLastError());
return 0;
}
// Prepare socket for listening
if (listen(Listen, 5) == SOCKET_ERROR)
{
printf("listen() failed with error %d\n", WSAGetLastError());
return 0;
}
// Accept connections and assign to the completion port.
int GsStartLink=0;
printf("服务器等待.....\n");
while(TRUE)
{
SOCKADDR_IN ClientAddr; // 定义一个客户端得地址结构作为参数
int addr_length=sizeof(ClientAddr);
if ((Accept = WSAAccept(Listen, (SOCKADDR*)&ClientAddr, &addr_length, NULL, 0)) == SOCKET_ERROR)
{
printf("WSAAccept() failed with error %d\n", WSAGetLastError());
return 0;
}
LPCTSTR lpIP = inet_ntoa(ClientAddr.sin_addr); // IP
UINT nPort = ClientAddr.sin_port; // Port
printf("lpIP:%s nPort:%d sk:%d\n",lpIP,nPort,Accept);
//testing (将数据放入sever list,以便日后发送给client(最主要作用系发送通道号))
AddHostPlayList(Accept,(char*)&Accept);
// Create a socket information structure to associate with the socket
if ((PerHandleData = (LPPER_HANDLE_DATA) GlobalAlloc(GPTR,
sizeof(PER_HANDLE_DATA))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
return 0;
}
// Associate the accepted socket with the original completion port.
PerHandleData->Socket = Accept;
if (CreateIoCompletionPort((HANDLE)Accept, CompletionPort, (DWORD) PerHandleData,
0) == NULL)
{
printf("CreateIoCompletionPort failed with error %d\n", GetLastError());
return 0;
}
// Create per I/O socket information structure to associate with the
// WSARecv call below.
if ((PerIoData = (LPPER_IO_OPERATION_DATA) GlobalAlloc(GPTR, sizeof(PER_IO_OPERATION_DATA))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
return 0;
}
ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
PerIoData->BytesSEND = 0;
PerIoData->BytesRECV = 0;
PerIoData->DataBuf.len = 8192000;//DATA_BUFSIZE;
PerIoData->DataBuf.buf = LHxxRecvBuffer;//PerIoData->Buffer;
Flags = 0;
if (WSARecv(Accept, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,
&(PerIoData->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
//MessageBox(SAVE_HWND, "WSARecv() Accept", "erroe", MB_OK);
}
}
Sleep(10);
}
}
#9
看了半天WIN2K的实现代码还有逆向dll的东西,大概有点思路了。也不知道正确否。
贴子结了再说~
贴子结了再说~