#include <winsock2.h> #include <windows.h> #include <stdio.h> #include <conio.h>
#define PORT 5150 #define DATA_BUFSIZE 8192
typedef struct _SOCKET_INFORMATION { BOOL RecvPosted; CHAR Buffer[DATA_BUFSIZE]; WSABUF DataBuf; SOCKET Socket; DWORD BytesSEND; DWORD BytesRECV; struct _SOCKET_INFORMATION *Next; }SOCKET_INFORMATION,*LPSOCKET_INFORMATION;
//#define WM_SOCKET(WM_USER + 1) #define WM_SOCKET 1001
void CreateSocketInformation(SOCKET s); LPSOCKET_INFORMATION GetSocketInformation(SOCKET s); void FreeSocketInformation(SOCKET s);
HWND MakeWorkerWindow(void); LRESULT CALLBACK WindowProc(HWND hwnd,UINT sMsg,WPARAM wParam,LPARAM lParam);
LPSOCKET_INFORMATION SocketinfoList;
void main(void) { MSG msg; DWORD Ret; SOCKET Listen; SOCKADDR_IN InternetAddr; HWND Window; WSADATA wsaData;
if((Window = MakeWorkerWindow()) == NULL) return; if((Ret = WSAStartup (MAKEWORD(2,2),&wsaData)) != 0) { printf("WSAStartuu failed witf error %d\n",Ret); return; } // if((Listen =socket(AF_INET,SOCK_STREAM,0)) == INVALID_SOCKET); Listen =socket(AF_INET,SOCK_STREAM,0); if(Listen == SOCKET_ERROR) { printf("socket() failed with error %d\n",WSAGetLastError()); return; }
WSAAsyncSelect(Listen,Window,WM_SOCKET,FD_ACCEPT|FD_CLOSE); InternetAddr.sin_family = AF_INET; InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY); InternetAddr.sin_port = htons(PORT); // if(bind(Listen,(PSOCKADDR)&InternetAddr,sizeof(InternetAddr)) == SOCKET_ERROR ) if(bind(Listen,(struct sockaddr *)&InternetAddr,sizeof(InternetAddr)) == SOCKET_ERROR ) { printf("bind() failed with error %d\n",WSAGetLastError()); return; } if(listen(Listen,5)) { printf("Listen() failed with error %d\n",WSAGetLastError()); return; }
while(Ret = GetMessage(&msg,NULL,0,0)) { if(Ret == -1) { printf("GetMessage() failed with error %d\n",GetLastError()); return; } TranslateMessage(&msg); DispatchMessage(&msg); }
}
LRESULT CALLBACK WindowPro(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(WSAGETSELECTERROR(lParam)) { case FD_ACCEPT: if((Accept = accept(wParam,NULL,NULL)) == INVALID_SOCKET) { printf("accept() failed with error %d\n",WSAGetLastError()); break; } 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); 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 { SocketInfo->BytesRECV = RecvBytes; } } 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 { SocketInfo->BytesSEND += SendBytes; } } if(SocketInfo->BytesSEND == SocketInfo->BytesRECV) { SocketInfo->BytesSEND = 0; SocketInfo->BytesRECV = 0; 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); }
void CreateSocketInformation(SOCKET s) { LPSOCKET_INFORMATION SI; if((SI = (LPSOCKET_INFORMATION)GlobalAlloc(GPTR, sizeof(SOCKET_INFORMATION))) == NULL) { printf("GlobalAlloc() failed with error %d\n",GetLastError()); return; }
SI->Socket = s; SI->RecvPosted = FALSE; SI->BytesSEND = 0; SI->BytesRECV = 0; SI->Next = SocketinfoList; SocketinfoList =SI; }
LPSOCKET_INFORMATION GetSocketInformation(SOCKET s) { SOCKET_INFORMATION *SI = SocketinfoList; while(SI) { if(SI->Socket == s) return SI; SI = SI->Next; } return NULL; }
void FreeSocketInformation(SOCKET s) { SOCKET_INFORMATION *SI = SocketinfoList; SOCKET_INFORMATION *PrevSI = NULL; while (SI) { if(SI->Socket == s) { if(PrevSI) PrevSI->Next = SI->Next; else SocketinfoList = SI->Next; closesocket(SI->Socket); GlobalFree(SI); return; } PrevSI = SI; SI = SI->Next; } }
HWND MakeWorkerWindow(void) { WNDCLASS wndclass; CHAR *ProviderClass = "AsyncSelect"; HWND Window;
wndclass.style = CS_HREDRAW; wndclass.lpfnWndProc = (WNDPROC)WindowPro; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = NULL; wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = ProviderClass;
if(RegisterClass(&wndclass) == 0) { printf("RegisterClass() failed with error %d \n",GetLastError()); return NULL; }
if((Window = CreateWindow( ProviderClass, "", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL)) == NULL) { printf("CreateWindow() failed with error %d\n",GetLastError()); return NULL; } return Window; }

|