LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { SOCKET Accept; LPSOCKET_INFORMATION SocketInfo; DWORD RecvBytes, SendBytes; DWORD Flags; if (uMsg == WM_SOCKET) { if (WSAGETSELECTERROR(lParam)) { printf("Socket failed with error %d\n", WSAGETSELECTERROR(lParam)); FreeSocketInformation(wParam); } else { switch(WSAGETSELECTEVENT(lParam)) { case FD_ACCEPT: if ((Accept = accept(wParam, NULL, NULL)) == INVALID_SOCKET) { printf("accept() failed with error %d\n", WSAGetLastError()); break; } // Create a socket information structure to associate with the // socket for processing I/O. CreateSocketInformation(Accept); printf("Socket number %d connected\n", Accept); WSAAsyncSelect(Accept, hwnd, WM_SOCKET, FD_READ|FD_WRITE|FD_CLOSE); break; case FD_READ: SocketInfo = GetSocketInformation(wParam); // Read data only if the receive buffer is empty. if (SocketInfo->BytesRECV != 0) { SocketInfo->RecvPosted = TRUE; return 0; } else { SocketInfo->DataBuf.buf = SocketInfo->Buffer; SocketInfo->DataBuf.len = DATA_BUFSIZE; Flags = 0; if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes, &Flags, NULL, NULL) == SOCKET_ERROR) { if (WSAGetLastError() != WSAEWOULDBLOCK) { printf("WSARecv() failed with error %d\n", WSAGetLastError()); FreeSocketInformation(wParam); return 0; } } else // No error so update the byte count { SocketInfo->BytesRECV = RecvBytes; } } // DO NOT BREAK HERE SINCE WE GOT A SUCCESSFUL RECV. Go ahead // and begin writing data to the client. case FD_WRITE: SocketInfo = GetSocketInformation(wParam); if (SocketInfo->BytesRECV > SocketInfo->BytesSEND) { SocketInfo->DataBuf.buf = SocketInfo->Buffer + SocketInfo->BytesSEND; SocketInfo->DataBuf.len = SocketInfo->BytesRECV - SocketInfo->BytesSEND; if (WSASend(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &SendBytes, 0, NULL, NULL) == SOCKET_ERROR) { if (WSAGetLastError() != WSAEWOULDBLOCK) { printf("WSASend() failed with error %d\n", WSAGetLastError()); FreeSocketInformation(wParam); return 0; } } else // No error so update the byte count { SocketInfo->BytesSEND += SendBytes; } } if (SocketInfo->BytesSEND == SocketInfo->BytesRECV) { SocketInfo->BytesSEND = 0; SocketInfo->BytesRECV = 0; // If a RECV occurred during our SENDs then we need to post an FD_READ // notification on the socket. if (SocketInfo->RecvPosted == TRUE) { SocketInfo->RecvPosted = FALSE; PostMessage(hwnd, WM_SOCKET, wParam, FD_READ); } } break; case FD_CLOSE: printf("Closing socket %d\n", wParam); FreeSocketInformation(wParam); break; } } return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam); }
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { SOCKET sd; LPSOCKET_INFORMATION SocketInfo; DWORD RecvBytes, SendBytes; DWORD Flags; switch (Message) { case WM_CREATE: createElements(hwnd); break; case WM_SOCKET: if (WSAGETSELECTERROR(lParam)) { printf("Socket failed with error %d\n", WSAGETSELECTERROR(lParam)); FreeSocketInformation(wParam); } else { switch (WSAGETSELECTEVENT(lParam)) { case FD_CONNECT: break; case FD_ACCEPT: if ((sd = accept(wParam, NULL, NULL)) == INVALID_SOCKET) { break; } CreateSocketInformation(sd); WSAAsyncSelect(sd, hwnd, WM_SOCKET, FD_READ | FD_CLOSE); break; case FD_READ: SocketInfo = GetSocketInformation(wParam); // Read data only if the receive buffer is empty. if (SocketInfo->BytesRECV != 0) { SocketInfo->RecvPosted = TRUE; return 0; } else { SocketInfo->DataBuf.buf = SocketInfo->Buffer; SocketInfo->DataBuf.len = DATA_BUFSIZE; Flags = 0; if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes, &Flags, NULL, NULL) == SOCKET_ERROR) { if (WSAGetLastError() != WSAEWOULDBLOCK) { printf("WSARecv() failed with error %d\n", WSAGetLastError()); FreeSocketInformation(wParam); return 0; } } else { // No error so update the byte count SocketInfo->BytesRECV = RecvBytes; } break; } break; case FD_WRITE: SocketInfo = GetSocketInformation(wParam); if (SocketInfo->BytesRECV > SocketInfo->BytesSEND) { SocketInfo->DataBuf.buf = SocketInfo->Buffer + SocketInfo->BytesSEND; SocketInfo->DataBuf.len = SocketInfo->BytesRECV - SocketInfo->BytesSEND; if (WSASend(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &SendBytes, 0, NULL, NULL) == SOCKET_ERROR) { if (WSAGetLastError() != WSAEWOULDBLOCK) { printf("WSASend() failed with error %d\n", WSAGetLastError()); FreeSocketInformation(wParam); return 0; } } else { // No error so update the byte count SocketInfo->BytesSEND += SendBytes; } } if (SocketInfo->BytesSEND == SocketInfo->BytesRECV) { SocketInfo->BytesSEND = 0; SocketInfo->BytesRECV = 0; // If a RECV occurred during our SENDs then we need to post an FD_READ // notification on the socket. if (SocketInfo->RecvPosted == TRUE) { SocketInfo->RecvPosted = FALSE; PostMessage(hwnd, WM_SOCKET, wParam, FD_READ); } } break; case FD_CLOSE: printf("Closing socket %d\n", wParam); FreeSocketInformation(wParam); break; } } break; case WM_DESTROY: // Terminate program PostQuitMessage(0); break; default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; }