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