Hi,

I am writing a UDP based multi-threaded server in C on linux platform. I am facing this perticular problem. I launch a new thread when when first packet from client is received on the server port. Now I want that, all subseqent send/recv between that client and server should happen in the new thread i just created. But in my case every new packet received from the same client causes server to spawn the new thread. How can I get it work the way I want it to work?

Following is the code where I spawn new thread.

Code:
while (1)
	{
		signal(SIGINT,exit_cleanup);
		if (shareddb->threadcount >= MAX_XCLIENTS)
		{
			printf("Maximum limit reached for client requests. Can not accept anymore requests.\n");
		} else {

			ServerSock[shareddb->threadcount]=getXSocket(&shareddb->serversockid[shareddb->threadcount]);

			//printf("Socket: %d\n",shareddb->serversockid[shareddb->threadcount]);

			if (ServerSock[shareddb->threadcount] == NULL)
			{
				exit(1);
			}
			
			if (setsockopt(shareddb->serversockid[shareddb->threadcount],SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) 
			{
				perror("setsockopt");
			}
			if ((bind(shareddb->serversockid[shareddb->threadcount],(XSocket *)ServerSock[shareddb->threadcount],sizeof(XSocket))) == -1 )
			{
				perror("Server Socket Bind Error:");
			}
			
			XServerSockid=shareddb->serversockid[shareddb->threadcount];

			if ((numbytes=recvfrom(XServerSockid,(XPacket *)&xpacket,sizeof(XPacket),0,(XSocket *)&RemoteSock, &sin_size)) == -1) {
				perror("recvfrom");
				exit(1);
			}
			//signal(SIGINT,exit_cleanup);

			printf("UDP Connection received from XClient Source IP %s Port:%d Socket: %d \n",inet_ntoa(RemoteSock.sin_addr),ntohs(RemoteSock.sin_port),shareddb->serversockid[shareddb->threadcount]);
		
			memcpy(&threadsdata.xpacket,&xpacket,sizeof(XPacket));
			memcpy(&threadsdata.xsocket,&RemoteSock,sizeof(XSocket_in));
			threadsdata.ServerSockid=shareddb->serversockid[shareddb->threadcount];
			threadsdata.first=1;

			rc=pthread_create(&shareddb->clientthreadid[shareddb->threadcount],&attr,HandleXConns,(void *)&threadsdata);
					
			if (rc){
				printf("ERROR; return code from pthread_create() is %d\n", rc);
				exit(-1);
			} else {
				memset(debugstr,'\0',sizeof(debugstr));
				sprintf(debugstr,"XServer: Thread started id: %d \n",(int)shareddb->clientthreadid[shareddb->threadcount]);
				dbgtrace(__FUNCTION__,debugstr);
				
				shareddb->threadcount++;
			}
		}
	}
When I run it I see following output. (Marked the line showing problem area )

./xserver
main : Shared memory for shared information database is created: id = 173473825
main : Shared memory pointer acquired: address = 0x0805cddc
UDP Connection received from XClient Source IP 10.6.250.55 Port:32811 Socket: 3
decodeXpacket : Version: 0x0001 Opcode: 0x0002 Message length: 1
decodeXpacket : Received XDMCP "Query" Packet.
decodeXpacket : Decoding XDMCP "Query" Packet.
decodeXpacket : Authenetication name length: 0
decodeXpacket : Authorization Data: 0
sendXpacket : Sending XDMCP "Willing" Packet.
sendXpacket : version: 0x0001 opcode: 0x0005 Message length: 31 Authname: 0x00
sendXpacket : XDMCP "Willing" Packet sent.

main : XServer: Thread started id: 8194 <<<<< Thread 1
UDP Connection received from XClient Source IP 10.6.250.55 Port:32811 Socket: 6 <<<< This should be received in Thread 1
main : XServer: Thread started id: 16387 <<<< Thread 2 (not required)
Unknown Packet. Can not proceed. <<<Errors as the this is continuation packet for Thread 1.
sendXpacket : Sending XDMCP "Decline" Packet.
sendXpacket : version: 0x0001 opcode: 0x0009 Message length: 6144 Authname: 0x00
sendXpacket : XDMCP "Decline" Packet sent.
Here is the snippet of the code in thread handler function HandleXConns()

Code:
void * HandleXConns(void *arg)
{
	struct thread_data *threadsdata;

	XPacket xpacket;
	XSocket_in xsocket,RemoteSock;
	XMode querytype;
	int addr_len,packetlen;
	boolean sendresult,receiveresult;
	int bytes_received;

	static int first=1;
	
	threadsdata=(struct thread_data *)arg;
	
	memcpy(&xpacket,&(threadsdata->xpacket),sizeof(XPacket));
	memcpy(&xsocket,&(threadsdata->xsocket),sizeof(XSocket_in));
	
	if (threadsdata->first && (htons(xpacket.opcode) == QUERY))
	{
		decodeXpacket(&xpacket);
		threadsdata->first=0;
	} else if (threadsdata->first && (htons(xpacket.opcode) == INDIRECTQUERY))
	{
		decodeXpacket(&xpacket);
		threadsdata->first=0;
	} else {
		printf("Unknown Packet. Can not proceed.\n");
		declinestatus = 2;
		sendXpacket(DECLINE,threadsdata->ServerSockid,xsocket);
		declinestatus = 0;
		pthread_exit(NULL);
	}
	
	querytype=WILLING;
	if ((sendresult=sendXpacket(querytype,threadsdata->ServerSockid,xsocket)) == FALSE)
		{
			memset(debugstr,'\0',sizeof(debugstr));
			sprintf(debugstr,"XDMCP session failed. Could not send the \"%s\"packet.\n",decodeIPCMessage(querytype));
			dbgtrace(__FUNCTION__,debugstr);
			undbgtrace(__FUNCTION__,debugstr);
			//terminateall(__FUNCTION__);
			pthread_exit(NULL);
		} else {			
			printf("\n");
			memset(xpacket.data,'\0',sizeof(xpacket.data));
			packetlen=(genlength + sizeof(xpacket.data));
			addr_len=sizeof(XSocket);
			
			bytes_received=recvfrom(threadsdata->ServerSockid, (XPacket *)&xpacket, packetlen, 0,(XSocket *)&RemoteSock, &addr_len); 

			memset(debugstr,'\0',sizeof(debugstr));
			sprintf(debugstr,"Total Bytes received : %d\n",bytes_received);
			dbgtrace(__FUNCTION__,debugstr);
....contd..
Is there anything obvious that I am missing here.?

Thanks,