Thread: Sockets and threads

  1. #1
    Registered User
    Join Date
    Jan 2006
    Location
    Europe/Belgrade
    Posts
    78

    Sockets and threads

    Hi,
    I made some tests with passing sockets to the threads and there's a problem with the following code.
    First, here's the client who's connecting to the server. It sends 1000 times a number to the server, everything works fine.

    Code:
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/un.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <netdb.h>
    
    
    int main(int argc, char* argv[])
    {
    	const int PORT = 10000;
    	struct sockaddr_in socketAddress;
    	int socketFd = socket(AF_INET, SOCK_STREAM, 0);
    	socketAddress.sin_family = AF_INET;
    	hostent* he = gethostbyname("localhost");
    	socketAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
    	socketAddress.sin_port = htons(PORT);
    	socklen_t addressLen = sizeof(socketAddress);
    	int res = connect(socketFd, (struct sockaddr*)&socketAddress, addressLen);
    	if (res == -1)
    		perror("connect");
    	for (int i = 1; i <= 1000; i++)
    	{
    		int no;
    		write(socketFd, &i, sizeof(int));
    		read(socketFd, &no, sizeof(int));
    		printf("read: %d\n", no);
    	}
    	close(socketFd);
    }
    Here's the server who's accepting connections and responses by incrementing received number by one:

    Code:
    #include <pthread.h>
    #include <errno.h>
    #include <sys/ioctl.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <vector>
    #include <iostream>
    
    
    using namespace std;
    
    
    void* run(void* params)
    {
    	int* fd = (int*)params;
    	int no;
    	read(*fd, &no, sizeof(int));
    	printf("read: %d\n", no);
    	no++;
    	write(*fd, &no, sizeof(int));
    	return NULL;
    }
    
    
    int main()
    {
    	const int PORT = 10000;
    	int serverFd = socket(PF_INET, SOCK_STREAM, 0);
    	int yes = 1;
    	setsockopt(serverFd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
    	sockaddr_in serverAddress;
    	serverAddress.sin_family = AF_INET;
    	serverAddress.sin_port = htons(PORT);
    	serverAddress.sin_addr.s_addr = INADDR_ANY;
    	memset(&(serverAddress.sin_zero), '\0', 8);
    	bind(serverFd, (struct sockaddr*)&serverAddress, sizeof(struct sockaddr));
    	listen(serverFd, 5);
    	
    	fd_set readFds, testFds;
    	FD_ZERO(&readFds);
    	FD_SET(serverFd, &readFds);
    	while (true)
    	{
    		vector<pthread_t> fds;
    		fds.clear();
    		testFds = readFds;
    		int res = select(FD_SETSIZE, &testFds, (fd_set*)0, (fd_set*)0, (struct timeval*)0);
    		if (res < 1)
    		{
    			perror("select()");
    			exit(1);
    		}
    		for (int fd = 0; fd < FD_SETSIZE; fd++)
    			if (FD_ISSET(fd, &testFds))
    			{
    				if (fd == serverFd)
    				{
    					struct sockaddr_in clientAddress;
    					socklen_t clientLen = sizeof(clientAddress);
    					int clientFd = accept(serverFd, (struct sockaddr*)&clientAddress, &clientLen);
    					FD_SET(clientFd, &readFds);
    				}
    				else
    				{
    					int nread;
    					ioctl(fd, FIONREAD, &nread);
    					if (nread == 0)
    					{
    						close(fd);
    						FD_CLR(fd, &readFds);
    					}
    					else
    					{
    /*
    						pthread_t th;
    						pthread_create(&th, NULL, &run, &fd);
    						fds.push_back(th);
    */
    						run(&fd);
    					}
    				}
    			}
    		cout << "fds.size()=" << fds.size() << endl;
    //		for (int i = 0; i < fds.size(); i++)
    //			pthread_join(fds[i], NULL);
    	}
    }
    The problem is following: server works fine if it calls run() and passes the socket file descriptor to it. But if I try to make threads to start run() and join them later, then it works for some time and it stops (receives few numbers or few hundreds but never receives them all). Those lines in code are commented out, if they are enabled, server creates threads for run().
    What is the reason of such behaviour? Are threads created too quickly?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > pthread_create(&th, NULL, &run, &fd);
    You're passing a pointer to a local variable, which gets changed in between you creating the thread, and the new thread getting a chance to look at it with
    int* fd = (int*)params;
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jan 2006
    Location
    Europe/Belgrade
    Posts
    78
    Thanks.

  4. #4
    Registered User
    Join Date
    Jun 2007
    Posts
    7
    I've been looking for code like this to pull apart for a bit, but when I try to compile the server It throws an error.

    Code:
    /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/cstdlib:135: error: ‘::system’ has not been declared
    is there any reason why I'm getting this error? Is it the libraries I have installed? If so which should I be getting? I'm running Ubuntu 7.04 (feisty)

  5. #5
    Registered User
    Join Date
    Jan 2006
    Location
    Europe/Belgrade
    Posts
    78
    Code:
    g++ client.cpp -o client 
    g++ server.cpp -o server -lpthread
    compiles client and server. Beside standard library you need only thread library which is probably installed during Linux installation.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Programming chat client, need some help (sockets & threads)
    By lalilulelo17 in forum Linux Programming
    Replies: 1
    Last Post: 04-19-2008, 04:01 AM
  2. Sharing sockets among threads
    By Hawkin in forum Networking/Device Communication
    Replies: 19
    Last Post: 02-04-2008, 04:13 PM
  3. [newb] how to use threads with sockets ?
    By jabka in forum C Programming
    Replies: 1
    Last Post: 08-07-2007, 11:51 AM
  4. Library for pool, sockets, threads
    By Mortissus in forum C++ Programming
    Replies: 13
    Last Post: 07-14-2007, 07:41 AM
  5. Sockets....
    By G'n'R in forum Networking/Device Communication
    Replies: 15
    Last Post: 09-19-2003, 04:14 AM