WSARecv 投递缓冲区也要对齐???不然就10014!

【转】WSARecv 投递缓冲区也要对齐???不然就10014!

本文转自http://blog.vckbase.com/zaboli/archive/2008/05/07/33541.aspx

如果把下面代码中背景色为绿色部分的 int iAlign = 4; 其中的 4 改为1或2,WSARecv就会返回 10014 错误。看来WSARecv 的投递的缓冲区也是要求对齐的。。正是因为这个问题。。浪费了我一天的时间调试我的内存池代码。。5555555555

 

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

#define  DATA_BUFSIZE 4096

void  main()  {
  
//-----------------------------------------
  
// Declare and initialize variables
  WSABUF DataBuf;
  
char buffer[DATA_BUFSIZE];
  DWORD EventTotal 
= 0
    RecvBytes 
= 0
    Flags 
= 0
    BytesTransferred 
= 0
    CallBack 
= 0;
  WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];
  WSAOVERLAPPED AcceptOverlapped;
  SOCKET ListenSocket, AcceptSocket;

  
//-----------------------------------------
  
// Initialize Winsock
  WSADATA wsaData;
  WSAStartup(MAKEWORD(
2,2), &wsaData);

  
//-----------------------------------------
  
// Create a listening socket bound to a local
  
// IP address and the port specified
  ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  u_short port 
= 27015;
  
char* ip;
  sockaddr_in service;
  service.sin_family 
= AF_INET;
  service.sin_port 
= htons(port);
  hostent
* thisHost;
  thisHost 
= gethostbyname("");
  ip 
= inet_ntoa (*(struct in_addr *)*thisHost->h_addr_list);
    
  service.sin_addr.s_addr 
= inet_addr(ip);

  
//-----------------------------------------
  
// Bind the listening socket to the local IP address
  
// and port number
  bind(ListenSocket, (SOCKADDR *&service, sizeof(SOCKADDR));

  
//-----------------------------------------
  
// Set the socket to listen for incoming
  
// connection requests
  listen(ListenSocket, 1);
  printf(
"Listening ");

  
//-----------------------------------------
  
// Accept and incoming connection request
  AcceptSocket = accept(ListenSocket, NULL, NULL);
  printf(
"Client Accepted ");

  
//-----------------------------------------
  
// Create an event handle and setup an overlapped structure.
  EventArray[EventTotal] = WSACreateEvent();
  ZeroMemory(
&AcceptOverlapped, sizeof(WSAOVERLAPPED));
  AcceptOverlapped.hEvent 
= EventArray[EventTotal];
  DataBuf.len 
= DATA_BUFSIZE;
  DataBuf.buf 
= buffer;
  EventTotal
++;

  LPWSABUF lpwsaBuf;

  //int iAlign = 1;
  int iAlign = 4;

  lpwsaBuf = (LPWSABUF) ((new CHAR[sizeof(WSABUF) + iAlign]) + iAlign);//pOverlapBuff->GetWSABuffer();
  lpwsaBuf->buf = new CHAR[52];
  lpwsaBuf->len = 52;
  


//-----------------------------------------
  
// Call WSARecv to receive data into DataBuf on 
  
// the accepted socket in overlapped I/O mode
  if (WSARecv(AcceptSocket, lpwsaBuf, 1&RecvBytes, &Flags, &AcceptOverlapped, NULL) == SOCKET_ERROR) 
  
{
      
if (WSAGetLastError() != WSA_IO_PENDING)
      
{
          printf(
"Error occured at WSARecv() %d ",WSAGetLastError());
          closesocket(AcceptSocket);
          
return;
      }

  }


  
//-----------------------------------------
  
// Process overlapped receives on the socket
  while (1{
    DWORD Index;

    
//-----------------------------------------
    
// Wait for the overlapped I/O call to complete
    Index = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE);

    
//-----------------------------------------
    
// Reset the signaled event
    WSAResetEvent(EventArray[Index - WSA_WAIT_EVENT_0]);

    
//-----------------------------------------
    
// Determine the status of the overlapped event
    WSAGetOverlappedResult(AcceptSocket, &AcceptOverlapped, &BytesTransferred, FALSE, &Flags);

    
//-----------------------------------------
    
// If the connection has been closed, close the accepted socket
    if (BytesTransferred == 0{
      printf(
"Closing Socket %d ", AcceptSocket);
      closesocket(AcceptSocket);
      WSACloseEvent(EventArray[Index 
- WSA_WAIT_EVENT_0]);
      
return;
    }


    
//-----------------------------------------
    
// If data has been received, echo the received data
    
// from DataBuf back to the client
    if (WSASend(AcceptSocket, &DataBuf, 1&RecvBytes, Flags, &AcceptOverlapped, NULL) == SOCKET_ERROR)
      printf(
"WSASend() is busted ");

    
//-----------------------------------------        
    
// Reset the changed flags and overlapped structure
    Flags = 0;
    ZeroMemory(
&AcceptOverlapped, sizeof(WSAOVERLAPPED));

    AcceptOverlapped.hEvent 
= EventArray[Index - WSA_WAIT_EVENT_0];

    
//-----------------------------------------
    
// Reset the data buffer
    DataBuf.len = DATA_BUFSIZE;
    DataBuf.buf 
= buffer;
  }

}

 

之所以转载这篇文章,是因为我也遇到了同样的问题,总是10014错误,整的我都要崩溃了,只差没把机器给砸了!谁知到最后竟然是好不容易弄的PER_IO_CONTEXT内存池对齐搞出的问题,幸亏看到“玻璃小屋”的这篇,不然要疯了!

以后切记!

你可能感兴趣的:(WSARecv 投递缓冲区也要对齐???不然就10014!)