Results 1 to 13 of 13

Thread: Multithreaded Socket Server

  1. #1

    Thread Starter
    Fanatic Member pradeepkrao's Avatar
    Join Date
    Sep 2001
    Location
    New Jersey
    Posts
    534

    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
    Learn by others experience as you cannot live long to experience them all.
    www.freewebs.com/pradeepkrao

    LOOK AT MY GAMES AT MY WEB SITE.

  2. #2
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    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.

  3. #3

    Thread Starter
    Fanatic Member pradeepkrao's Avatar
    Join Date
    Sep 2001
    Location
    New Jersey
    Posts
    534

    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
    Learn by others experience as you cannot live long to experience them all.
    www.freewebs.com/pradeepkrao

    LOOK AT MY GAMES AT MY WEB SITE.

  4. #4
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    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.

  5. #5

    Thread Starter
    Fanatic Member pradeepkrao's Avatar
    Join Date
    Sep 2001
    Location
    New Jersey
    Posts
    534

    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.
    Learn by others experience as you cannot live long to experience them all.
    www.freewebs.com/pradeepkrao

    LOOK AT MY GAMES AT MY WEB SITE.

  6. #6
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    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.

  7. #7

    Thread Starter
    Fanatic Member pradeepkrao's Avatar
    Join Date
    Sep 2001
    Location
    New Jersey
    Posts
    534

    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--;
    
    
    }
    Learn by others experience as you cannot live long to experience them all.
    www.freewebs.com/pradeepkrao

    LOOK AT MY GAMES AT MY WEB SITE.

  8. #8
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Looks good.
    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.

  9. #9

    Thread Starter
    Fanatic Member pradeepkrao's Avatar
    Join Date
    Sep 2001
    Location
    New Jersey
    Posts
    534

    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
    Learn by others experience as you cannot live long to experience them all.
    www.freewebs.com/pradeepkrao

    LOOK AT MY GAMES AT MY WEB SITE.

  10. #10
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    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.

  11. #11

    Thread Starter
    Fanatic Member pradeepkrao's Avatar
    Join Date
    Sep 2001
    Location
    New Jersey
    Posts
    534

    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
    Learn by others experience as you cannot live long to experience them all.
    www.freewebs.com/pradeepkrao

    LOOK AT MY GAMES AT MY WEB SITE.

  12. #12
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    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.

  13. #13

    Thread Starter
    Fanatic Member pradeepkrao's Avatar
    Join Date
    Sep 2001
    Location
    New Jersey
    Posts
    534

    Hi

    Yes...

    Now its working great...

    Thankx...


    Pradeep
    Learn by others experience as you cannot live long to experience them all.
    www.freewebs.com/pradeepkrao

    LOOK AT MY GAMES AT MY WEB SITE.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width