宕在::accept函数里,有人遇到过么?

时间:2021-11-13 20:02:33
> wshtcpip.dll!71a412e5() 
  [下面的框架可能不正确和/或缺失,没有为 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++

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


#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++

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


#9


看了半天WIN2K的实现代码还有逆向dll的东西,大概有点思路了。也不知道正确否。
贴子结了再说~