【转】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;
}
}
#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内存池对齐搞出的问题,幸亏看到“玻璃小屋”的这篇,不然要疯了!
以后切记!