Non-blocking Sockets

Started by Freddy, August 09, 2007, 10:35:19 PM

Previous topic - Next topic

Freddy

Hi!
Can anyone post an example on how to create simple server using Winsock, that do not block the GUI while it's listening for connections?

Thanks

frankie

Non blocking call is annoying to program, why don't use a dirrent approach: create a new thread and make the call in this thread so only it will get blocked while the principal thread continues to run. In this way you can define the mechanism which tells you that a data packet is available.
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

Freddy

Yes, it seems creating a thread is a better option.
Thanks for the idea.
So, I would use _beginthread() and link with Pelles C multithread library (/MT option), right?

frankie

Right.
You can also use the win32 API call CreateThread
HANDLE CreateThread(

    LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to thread security attributes 
    DWORD dwStackSize, // initial thread stack size, in bytes
    LPTHREAD_START_ROUTINE lpStartAddress, // pointer to thread function
    LPVOID lpParameter, // argument for new thread
    DWORD dwCreationFlags, // creation flags
    LPDWORD lpThreadId // pointer to returned thread identifier
   );
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

Freddy

OK. Thanks!

What's the best way to send a file with sockets?
I know how to use Winsock, but I have no clue how would I send a file checking the size of chunks, etc.

Thanks again.

codamateur

Example of a server written in C without thread , using non-blocking sockets

to test:
run telnet.exe and choose localhost as IP, port=23,  to connect to.
(the server doesn't show a window)

//******************************************************


#include <windows.h>
#include <winsock.h>

#define MAXCLIENT 2
#define MAXBUF 512
#define PORT 23
#define WM_SOCKET1 (WM_USER+100)
#define WM_SOCKET2 (WM_USER+101)

LRESULT CALLBACK WndProcedure(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);

WNDCLASSEX wc={sizeof(WNDCLASSEX),0,WndProcedure,0,0,0,0,0,0,0,"vclass",0};

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine\
,int nCmdShow)
{

MSG Msg;

wc.hInstance=hInstance;
RegisterClassEx(&wc);

if(CreateWindowEx(0,"vclass",0,0,0,0,0,0,0,0,hInstance,0))
{
while(GetMessage(&Msg,NULL,0,0))
{
DispatchMessage(&Msg);
}
}
return 0;
}


LRESULT CALLBACK WndProcedure(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
char buff[MAXBUF];
int i;
unsigned int testmsg;
static SOCKET s;
static SOCKET s_client[MAXCLIENT];
static WSADATA wsa;
static SOCKADDR_IN sin;

testmsg=Msg-WM_SOCKET2;

if(testmsg<MAXCLIENT)
{
if(lParam==FD_READ)
{

recv(s_client[testmsg],buff,MAXBUF,0);
send(s_client[testmsg],"OK",2,0);
}
else
{
closesocket(s_client[testmsg]);
s_client[testmsg]=0;
}
}

else
{
switch(Msg)
{

case WM_SOCKET1:
i=0;
while(s_client[i]!=0 && i<MAXCLIENT)
i++;


if(i<MAXCLIENT)
{
s_client[i]=accept(s,0,0);
WSAAsyncSelect(s_client[i],hWnd,WM_SOCKET2+i,\
FD_CLOSE | FD_READ);
}
else
{
closesocket(accept(s,0,0));
}
break;

case WM_DESTROY:
for(i=0;i<MAXCLIENT;i++)  /*closing all sockets*/
if(s_client[i]) closesocket(s_client[i]);
closesocket(s);

WSACleanup();
MessageBox(0,"BYE!","SERVER",0);
PostQuitMessage(0);
break;

/*message received when the window is created: */
case WM_CREATE:
for(i=0;i<MAXCLIENT;i++)
s_client[i]=0;

WSAStartup(MAKEWORD(1,1),&wsa);

s=socket(AF_INET,SOCK_STREAM,0);
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=0;
sin.sin_port=htons(PORT);
bind(s,(LPSOCKADDR)&sin,sizeof(SOCKADDR_IN));
listen(s,0);
WSAAsyncSelect(s,hWnd,WM_SOCKET1,FD_ACCEPT);
break;
default:
return DefWindowProc(hWnd,Msg,wParam,lParam);
}
}
return 0;
}

codamateur

I have compiled this source code (notice the size ;)