im trying to make a Simple Client - Server application using Async Sockets, that will support Multiple connection on server side
i have read several tutorials and examples on the net but i have some problems and i hope some1 can help me fix them
1) When i close Server or Client , i cannot reconnect back , even with FD_CLOSE event code
2) FD_ACCEPT: doesn't display a message box when its connected , why is there something wrong?
3) Does this Server code is able to accept multiple connection at once? or ill need to recall the listen function each time i make a connection?
the code doesn't have anything more that sockets initialization and connection
hope some1 can point out the code errors.
Server Code
Code:
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib,"wsock32.lib")
#define WM_WSAASYNC (WM_USER +1)
#define WM_SOCKET 104
LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
void SockInit(HWND hwnd);
void SockListen(HWND hWnd);
SOCKET hSock;
SOCKET sTemp;
SOCKADDR_IN ServAdr;
sockaddr sockAddrClient;
int SPort = 4455;
void SockListen(HWND hWnd)
{ hSock = socket(AF_INET,SOCK_STREAM,0);
WSAAsyncSelect(hSock,hWnd,WM_WSAASYNC,FD_ACCEPT|FD_CLOSE|FD_READ);
ServAdr.sin_family=AF_INET;
ServAdr.sin_addr.s_addr=htonl(INADDR_ANY);
ServAdr.sin_port=htons(SPort);
bind(hSock,(LPSOCKADDR)&ServAdr,sizeof(struct sockaddr));
listen(hSock, 1);
}
void SockInit(HWND hwnd)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 0 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
PostQuitMessage(1);
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 0 )
{
WSACleanup();
PostQuitMessage(0);
}
}
LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
{
SockInit(hWnd);
SockListen(hWnd);
}
break;
case WM_DESTROY:
{
PostQuitMessage(0);
shutdown(wParam,SD_BOTH);
closesocket(wParam);
WSACleanup();
return 0;
}
break;
case WM_SOCKET:
{
switch(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
{
int size=sizeof(sockaddr);
sTemp = accept(wParam,&sockAddrClient,&size);
MessageBox(hWnd,"Server Accepted","Connection!",MB_ICONINFORMATION|MB_OK);
}
break;
case FD_READ:
{
//Not done yet
}
break;
case FD_CLOSE:
{
WSACleanup();
closesocket(wParam);
}
break;
}
}
}
return(DefWindowProc(hWnd, msg, wParam, lParam));
}
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd)
{
MSG msgs;
HWND hwnd;
WNDCLASSEX wClass;
ZeroMemory(&wClass,sizeof(WNDCLASSEX));
wClass.cbClsExtra=NULL;
wClass.cbSize=sizeof(WNDCLASSEX);
wClass.cbWndExtra=NULL;
wClass.hbrBackground=(HBRUSH)COLOR_WINDOW;
wClass.hCursor=LoadCursor(NULL,IDC_ARROW);
wClass.hIcon=NULL;
wClass.hIconSm=NULL;
wClass.hInstance=hInst;
wClass.lpfnWndProc=(WNDPROC)WinProc;
wClass.lpszClassName="Window Class";
wClass.lpszMenuName=NULL;
wClass.style=CS_HREDRAW|CS_VREDRAW;
RegisterClassEx(&wClass);
HWND hWnd=CreateWindowEx(NULL,"Window Class","Client",WS_OVERLAPPEDWINDOW, //WS_POPUP | WS_VISIBLE
400,
200,
500,
300,NULL,NULL,hInst,NULL);
ShowWindow(hWnd,nShowCmd);
ZeroMemory(&msgs,sizeof(UINT));
while(GetMessage(&msgs,NULL,0,0))
{
TranslateMessage(&msgs);
DispatchMessage(&msgs);
}
return 0;
}
Client Code
Code:
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib,"wsock32.lib")
#define WM_WSAASYNC (WM_USER +1)
#define WM_SOCKET 104
LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
void SockInit(HWND hwnd);
void SockListen(HWND hWnd);
void CloseSocket();
SOCKET hSock;
SOCKADDR_IN ServAdr;
int SPort = 4455;
void Connect(HWND hWnd)
{
int ConRes;
Sleep(1000);
begin:
Sleep(1000);
ServAdr.sin_family = AF_INET;
ServAdr.sin_addr.s_addr=inet_addr("127.0.0.1");
ServAdr.sin_port = htons (SPort);
hSock = socket (AF_INET,SOCK_STREAM,0);
ConRes=connect (hSock, (struct sockaddr *)&ServAdr,sizeof(ServAdr));
if (ConRes==-1)
{
goto begin;
}
else
{
WSAAsyncSelect(hSock,hWnd,WM_WSAASYNC,FD_READ|FD_CLOSE|FD_CONNECT);
}
return;
}
void SockInit(HWND hwnd)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 0 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
PostQuitMessage(1);
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 0 )
{
WSACleanup();
PostQuitMessage(0);
}
}
LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
{
SockInit(hWnd);
Connect(hWnd);
}
break;
case WM_DESTROY:
{
PostQuitMessage(0);
shutdown(wParam,SD_BOTH);
closesocket(wParam);
WSACleanup();
return 0;
}
break;
case WM_SOCKET:
{
switch(WSAGETSELECTEVENT(lParam))
{
case FD_CONNECT:
{
MessageBox(hWnd,"Server connected","Connection!",MB_ICONINFORMATION|MB_OK);
}
break;
case FD_READ:
{
//Not done yet
}
break;
case FD_CLOSE:
{
WSACleanup();
closesocket(wParam);
Connect(hWnd);
}
break;
}
}
}
return(DefWindowProc(hWnd, msg, wParam, lParam));
}
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd)
{
MSG msgs;
HWND hwnd;
WNDCLASSEX wClass;
ZeroMemory(&wClass,sizeof(WNDCLASSEX));
wClass.cbClsExtra=NULL;
wClass.cbSize=sizeof(WNDCLASSEX);
wClass.cbWndExtra=NULL;
wClass.hbrBackground=(HBRUSH)COLOR_WINDOW;
wClass.hCursor=LoadCursor(NULL,IDC_ARROW);
wClass.hIcon=NULL;
wClass.hIconSm=NULL;
wClass.hInstance=hInst;
wClass.lpfnWndProc=(WNDPROC)WinProc;
wClass.lpszClassName="Window Class";
wClass.lpszMenuName=NULL;
wClass.style=CS_HREDRAW|CS_VREDRAW;
RegisterClassEx(&wClass);
HWND hWnd=CreateWindowEx(NULL,"Window Class","Server",WS_OVERLAPPEDWINDOW, //WS_POPUP | WS_VISIBLE
400,
200,
300,
100,NULL,NULL,hInst,NULL);
ShowWindow(hWnd,nShowCmd);
ZeroMemory(&msgs,sizeof(UINT));
while(GetMessage(&msgs,NULL,0,0))
{
TranslateMessage(&msgs);
DispatchMessage(&msgs);
}
return 0;
}