Thread: Help with multithreaded sockets program

  1. #1
    Registered User
    Join Date
    Dec 2008
    Posts
    2

    Help with multithreaded sockets program

    Hello.

    I'm trying to learn how to use threads and sockets in C. To do this, I've written a program that does the following:
    1) Spawns a thread, which then starts listening on a server socket
    2) Opens a client socket, and sends a message through
    3) On the server side, reads the message and prints it out

    Here's my code:
    Code:
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <stdio.h>
    #include <pthread.h>
    #include <unistd.h>
    #include <errno.h>
    
    #define PORT_NO 1234
    	
    typedef int Socket;
    typedef pthread_t Thread;
    
    void* do_server(void*);
    void* do_client(void*);
    			
    int main(void) {
    	
    	Thread other_thread;
    	int ret = pthread_create(&other_thread, NULL, do_server, NULL);
    	if(ret < 0)
    		printf("Trouble creating thread in main...\n");
    	
    //	printf("%s", "Going to sleep...\n");
    	sched_yield();
    	sleep(2);
    //	printf("%s", "Waking up...\n");
    	
    	do_client(NULL);
    	
    	pthread_exit(NULL);
    	
        return 0;
    				
    }
    
    void* do_server(void* param) {
    	
    	printf("%s", "In server code...\n");
    	
    	Socket my_socket = socket( PF_INET , SOCK_STREAM , 0 );
    	if(my_socket < 0)
    		printf("%s", "Socket creation failed in server...\n");
    	struct sockaddr_in address;
    	address.sin_family = AF_INET;
    	address.sin_addr.s_addr = htonl(INADDR_ANY);
    	address.sin_port = htons(PORT_NO);
    						
    	int res = bind( my_socket, (struct sockaddr*) &address, sizeof(struct sockaddr_in));
    	
    	if(res < 0)
    		printf("Trouble binding socket...\n");
    	
    	res = listen( my_socket, 5 );
    	if(res < 0)
    		printf("Couldn't listen to socket...\n");
    	
    	struct sockaddr_in remote_address;
    	socklen_t remote_address_len;
    	Socket new_socket;
    	
    	printf("Accepting...\n");
    	new_socket = 
    		accept( my_socket,  (struct sockaddr*) &remote_address,
    							&remote_address_len);
    	
    	
    	if(new_socket < 0) {
    		printf("Couldn't accept connection...");
    		switch(errno) {
    		case EBADF:
    			printf("Bad file descriptor\n");
    			break;
    		case ENOTSOCK:
    			printf("Descriptor is not a socket\n");
    			break;
    		case EOPNOTSUPP:
    			printf("Operation not supported\n");	
    			break;
    		case EWOULDBLOCK:
    			printf("Would block\n");
    			break;
    		default:
    			printf("Unknown error code: %d\n", errno);
    			break;
    		}
    	}
    	
    	void* data = malloc(0x0400); /* 1k */
    	res = recv(new_socket, data, 1024, 0);
    	printf("%d bytes received", res);
    	
    	printf("%s\n", (char*) data);
    	free(data);
    	
    	shutdown(my_socket, 2);
    	shutdown(new_socket, 2);
    	
    	printf("Exiting server code...\n");
    	pthread_exit(NULL);
    }
    
    void* do_client(void* param) {
    	
    	printf("%s", "Running client code...\n");
    	
    	Socket my_socket = socket( PF_INET , SOCK_STREAM , 0 );
    	if(my_socket < 0)
    		printf("%s", "Socket creation failed in client...\n");
    	struct sockaddr_in address;
    	address.sin_family = AF_INET;
    	address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    	address.sin_port = htons(PORT_NO);
    	
    	int res = connect( my_socket, (struct sockaddr*) &address, sizeof(struct sockaddr));
    	if(res < 0)
    		printf("Trouble connecting...\n");
    	
    	const char MSSG[] = "Hello, there!";
    	
    	res = send( my_socket, MSSG, sizeof(MSSG), 0);
    	printf("%d bytes sent\n", res);
    	
    	printf("%s", "Going to sleep in client code...\n");
    	sched_yield();
    	sleep(2);
    	
    	shutdown(my_socket, 2);
    	printf("Client thread exiting...\n");
    	pthread_exit(NULL);
    	
    }
    This has *occasionally* worked, leading me to believe that I'm on the right track, but this is the output I'm getting now:
    Code:
    In server code...
    Accepting...
    Running client code...
    14 bytes sent
    Going to sleep in client code...
    Couldn't accept connection...Unknown error code: 22
    -1 bytes received
    Exiting server code...
    Client thread exiting...
    Does anyone know what I'm doing wrong? Thanks.
    Cooper

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    I believe errno 22 is Invalid Argument.
    Mainframe assembler programmer by trade. C coder when I can.

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    You aren't initializing remote_address_len. It needs to be set to sizeof(sockaddr_in). This is in the man page...
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Registered User
    Join Date
    Dec 2008
    Posts
    2
    Thanks, that fixed it. I was using the GNU C Standard Library manual, which (oddly) doesn't mention this.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can someome help me with a program please?
    By WinterInChicago in forum C++ Programming
    Replies: 3
    Last Post: 09-21-2006, 10:58 PM
  2. program structure with select sockets
    By n3v in forum Networking/Device Communication
    Replies: 9
    Last Post: 06-03-2006, 06:34 AM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM