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
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.
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?
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
);
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.
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;
}
I have compiled this source code (notice the size ;)