|
-
Jul 24th, 2003, 07:28 AM
#1
Thread Starter
Fanatic Member
Multithreaded Socket Server
Hi,
I have created a multi threaded socket server. But it is not behaving like one..
See the following code
Code:
/*Creating a Mutex*/
hSocketMutex = CreateMutex( NULL, FALSE, "SocketMutex" );
printf("%s: waiting for data on port TCP %u\n",module,SERVER_PORT);
for(;;)
{
cliLen = sizeof(sdstruct.cliAddr);
sdstruct.newSd = accept(sdstruct.sd, (struct sockaddr *) &sdstruct.cliAddr, &cliLen);
if(sdstruct.newSd<0)
{
perror("cannot accept connection ");
return 0;
}
/*Once a client requests I pass that socket structure to the Thread function which will handle that client request*/
hSock = CreateThread (NULL, 0,AcceptConnection, (LPVOID)&sdstruct, 0, &dwThreadId);
}
In the thread function..
Code:
DWORD WINAPI AcceptConnection(LPVOID lsock)
{
DWORD iRetVal;
SOCKET_STRUCT psock;
hSocketMutex= OpenMutex( SYNCHRONIZE, FALSE, "SocketMutex" );
iRetVal = WaitForSingleObject(hSocketMutex, INFINITE );
if( iRetVal == WAIT_FAILED )
{
printf("WAIT_FAILED\n");
return 0;
}
else if( iRetVal == WAIT_TIMEOUT )
{
printf("WAIT_TIMEOUT\n");
return 0;
}
else if( iRetVal == WAIT_OBJECT_0 )
{
printf("WAIT_OBJECT_0\n");
}
psock = (SOCKET_STRUCT)lsock;
memset(args,0,COM_ARGS);
if(GetParams(args,psock.newSd)>0)
{
strcpy(com_dat,args);
printf("%d\n",psock.newSd);
printf("%s: received from %s:TCP%d : %s\n\n", module,inet_ntoa(sdstruct.cliAddr.sin_addr),ntohs(sdstruct.cliAddr.sin_port), args);
memset(args,0,COM_ARGS);
ProcessData(psock.newSd);
}
/*else
{
printf("Command not received\n");
}*/
ReleaseMutex(hSocketMutex);
CloseHandle(hSocketMutex);
return 1;
}
Since I am using a Mutex though the client requested is accepted, it is served after the previous thread releases the Mutex.
All I want to know is how to overcome this.
If I dont create the mutex lock then there will be a clash of local/global variables..
Please let me know If there is a better method.
Thanks,
Pradeep
-
Jul 25th, 2003, 06:21 AM
#2
Remove global variables. Local (stack) variables are thread-safe anyway. Learn about TLS (Thread Local Storage).
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jul 25th, 2003, 07:36 AM
#3
Thread Starter
Fanatic Member
Hi
Hae Thanks,
I too found that when I printed the address of the local variable in the thread... they were different..
How can I pass the connfd of the accept call from the server to the thread..
I guess in the thread I will do..
Code:
SOCKET lSock;
memcpy(lSock,connfd,sizeof(SOCKET));
Can I do this.. By doing this can I forget the MUTEX and go further..
Thanks,
Pradeep
-
Jul 25th, 2003, 10:09 AM
#4
Make a single global SOCKET variable. Have a global autoreset event. When your main thread gets a response, let it set the SOCKET to the connection, spawn (or wake) the handler thread and wait for the event. The handler gets the SOCKET into its own memory (away from the global) and fires the event.
Sounds good to me.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jul 27th, 2003, 11:29 PM
#5
Thread Starter
Fanatic Member
Hi
Hi,
I have two solutions.. Tell me which one is better..
1)
Code:
main()
{
SOCKET con;
for( ; ; )
{
con = accept();
thread(con);
}
}
thread(SOCKET aSoc)
{
SOCKET tSoc;
char * Data;
tSoc = aSoc;
getData(&Data);
for( ; Data != NULL; )
{
send(tSoc,Data);
}
close(tSoc);
}
Is this OK.. Any way I will try this..
Other one is..
Code:
SOCKET gSoc[50];
main()
{
for( ; ; )
{
index = GetFreeSocket();
gSoc[index] = accept();
thread (index);
}
}
thread( int index)
{
//Process..
close[gSoc[index]);
}
Which is better.. ?
Thanks,
Pradeep
Last edited by pradeepkrao; Jul 27th, 2003 at 11:42 PM.
-
Jul 28th, 2003, 01:11 AM
#6
The first. Cast the SOCKET to an LPVOID to pass it. If you cannot (because of differnent sizes, I have no idea what a SOCKET is) or you don't want to, and you decide to pass by reference instead you MUST add synchronization of some sort.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jul 28th, 2003, 01:19 AM
#7
Thread Starter
Fanatic Member
Hi
Hi,
This is what I have done now...
Looks fine.. Have not done a regressive testing..
Code:
void main()
{
SOCKET connfd;
HANDLE tHwnd;
DWORD dwThreadId;
InitSocket(); // Finction to Init ....
for(;;)
{
int size = sizeof(theiraddr);
connfd = accept ( sockfd , (struct sockaddr *) &theiraddr ,&size );
if ( connfd < 0 )
{
printf("connection error\n");
break;
}
tHwnd = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)MyFuncThread, (LPVOID)connfd, 0, &dwThreadId );
if( tHwnd == INVALID_HANDLE_VALUE )
{
printf("Error %ld\n",GetLastError());
}
CloseHandle(tHwnd);
/* Function to be added */
}
}
void MyFuncThread(LPVOID aCon)
{
SOCKET con;
con = (SOCKET)aCon;
char dynPort[255];
char NewProcess[255];
memset(dynPort,0,sizeof(dynPort));
memset(NewProcess,0,sizeof(NewProcess));
sprintf(dynPort,"9980");
x++;
printf("%d - %s\n",x,dynPort);
int nw = send(con ,dynPort,sizeof(dynPort),0);
if( nw < 0 )
{
printf("error at write\n");
closesocket(con );
}
Sleep(200);
closesocket(con );
x--;
}
-
Jul 28th, 2003, 01:27 AM
#8
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jul 28th, 2003, 01:31 AM
#9
Thread Starter
Fanatic Member
Hi
Hae CornedBee,
Got a question..
If I have a Thread.. which calls some function... which in turn calls some other function..
Code:
main()
{
CreateThread(ThreadFunction);
}
ThreadFunction()
{
function1();
}
function1()
{
function2();
}
If the main creates 'n' threads.. will there be any clash when same functions are called by different threads... ?..
I guess I am asking something sensible..
Thanks,
Pradeep
-
Jul 28th, 2003, 05:03 AM
#10
The functions themselves do not clash. Local variables are separate for all threads.
Code that uses static or global variables, however, might clash.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jul 28th, 2003, 05:07 AM
#11
Thread Starter
Fanatic Member
Hi
Hae.. thankx...
Its running fine now......
Well I will let you know the status..
I am trying to make a RSH Daemon and Client ..
To Communicate from Unix to Windows..
Unix (Client)
Windows Server..
Thanks,
Pradeep
-
Jul 28th, 2003, 07:15 AM
#12
No idea what RSH is (remote shell?), but good luck!
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jul 28th, 2003, 07:25 AM
#13
Thread Starter
Fanatic Member
Hi
Yes...
Now its working great... 
Thankx...
Pradeep
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|