Thread: Cannot Accept Connections with Simple client/server program

  1. #1
    Registered User
    Join Date
    Nov 2007
    Posts
    96

    Cannot Accept Connections with Simple client/server program

    Hello, all I am trying to do is just make the code I was given work. However, whenever I try to accept incoming connections I get an error and am unable to. The code appears to be fine I am beginning to wonder if my permissions have something to do with it as I am just trying to connect with localhost.

    Code:
    Server Side:
    #include <netdb.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include "wl.h"
    
    int main(int argc, char *argv[]) {
    	int	port;		/* port number to connect to, on server */
    	int	queue_len=5;	/* length of waiting queue */
    	struct sockaddr_in	sin;	/* local "server" socket endpoint */
    	struct sockaddr_in	cin;	/* remote "client" socket endpoint */
    	int			calen;	/* remote "client" address length */
    	int	msock;		/* socket descriptor for connection */
    	int	ssock;		/* socket descriptor for service */
    	
    	char	mess_in[256];
    	char	mess_out[256];
    	int	pid;		/* pid of server (this) process */
    	int	i;		/* loop index */
    	int	nw,nr;		/* number read and number written */
    	int	nrsf;		/* number read so far, for multiple reads */
    
    	pid= getpid();
    	if(argc==1) {
    		port = WL_PORT;
    	} else if(argc==2) {
    		port = atoi(argv[2]);
    	} else {
    		fprintf(stderr,"ERROR: useage:  %s [<port>]\n", argv[0]);
    		exit(1);
    	}
    	#ifdef DEBUG
    		fprintf(stderr,"DEBUG: %d %s will listen on port %d\n", pid, argv[0], port);
    	#endif
    
    
    	/* Get a TCP based socket. */
    	// if((msock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
    	if((msock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
    		fprintf(stderr,"ERROR: %s Can't get a socket.\n", argv[0]);
    		exit(1);
    	}
    
    
    	/* Prepare the endpoint. (Let the system respond on all ip addresses) */
    	memset(&sin, 0, sizeof(sin));
    	sin.sin_family = AF_INET;
    	sin.sin_addr.s_addr = INADDR_ANY;
    	sin.sin_port = htons((u_short)port);
    	
    
    	/* Bind the socket to the local endpoint (port) */
    	if(bind(msock, (struct  sockaddr  *)&sin, sizeof(sin)) < 0) {
    		fprintf(stderr,"ERROR: %s Can't bind to port %d\n", argv[0], port);
    		exit(1);
    	}
    
    	if(listen(msock, queue_len) < 0) {
    		fprintf(stderr,"ERROR: %s Can't listen, queue_len = %d\n", argv[0], queue_len);
    		exit(1);
    	}	
    
    	while(1) {
    		if((ssock=accept(msock, (struct  sockaddr  *)&cin, &calen))<0){
    			fprintf(stderr,"ERROR: %s can not accept connection\n", argv[0]);
    		}
    
    		if(read(ssock, mess_in, 1) != 1) {
    			fprintf(stderr,"ERROR: %s can not read a message count. \n", argv[0]);
    			exit(1);
    		}
    		for(nrsf=1;  nrsf < mess_in[0]; nrsf+=nr) {
    			if((nr=read(ssock, mess_in+nrsf, mess_in[0]-nrsf))<=0) {
    				break;
    			}
    			#ifdef DEBUG
    				fprintf(stderr,"DEBUG: %d %s read nr = %d  nrssf = %d\n", pid, argv[0], nr, nrsf);
    			#endif
    		}
    		#ifdef DEBUG
    			fprintf(stderr,"DEBUG: %d %s final nr = %d  nrssf = %d\n", pid, argv[0], nr, nrsf);
    			fprintf(stderr,"DEBUG: %d %s read mess_in = %d \"%s\" from socket\n", pid, argv[0], mess_in[0], mess_in+1);
    		#endif
    
    
    		/* 
    		* Now write the message back, after using toupper in it.
    		*/
    		mess_out[0] = mess_in[0];
    		for(i=1; i<mess_in[0]; i++) {
    			mess_out[i] = toupper(mess_in[i]);
    		}
    
    		#ifdef DEBUG
    			fprintf(stderr,"DEBUG: %d %s write mess_out = %d \"%s\" to socket\n", pid, argv[0], mess_out[0], mess_out+1);
    		#endif
    
    		if((nw=write(ssock, mess_out, mess_out[0])) != mess_out[0]) {
    			fprintf(stderr,"ERROR: %s wrote %d out of %d.\n", argv[0], nw, mess_out[0]);
    			exit(1);
    		}
    	}
    }
    The program crashes when trying to execute the accept command and I have been rattling my brain trying to understand why. I have looked at documentation online and everything appears to be set up right.....I think

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Crashes how?
    Segmentation fault, Bus error (these are what I would call a crash - unplanned program exit)

    > fprintf(stderr,"ERROR: %s can not accept connection\n", argv[0]);
    Or do you get some of these?

    Use perror() to find out more information.
    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
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Code:
    else if(argc==2) {
    		port = atoi(argv[2]);
    if argc is 2 - argv[2] is NULL
    you need argv[1] in this case
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  4. #4
    Registered User
    Join Date
    Nov 2007
    Posts
    96
    I have no issue with compiling, however the output notifies me that I cannot accept the client connection. I will post the client code as well with the output. The code should run successful as others have had no issues, this is why I am thinking it may be something with the set-up of my system.

    Here is the rest:

    Client Code:

    Code:
    /*
    * File: wl.c
    * The start of a "Web Load" client program.
    */
    #include <netdb.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include "wl.h"
    
    int main(int argc, char *argv[]) {
    	char	*name;		/* domain name of server */
    	int	port;		/* port number to connect to, on server */
    	struct hostent 		*phostent;	/* for lookup of server ip address */
    	/* struct sockaddr_in	sin;		 socket endpoint */
    	int	s;		/* socket descriptor for connection */
    	int 	pid;		/* clinet (this process's) pid */
    	char	spid[8];	/* string version of pid */
    	char	mess_out[256] = "\0this is a lower case message. from pid = ";
    	int	mess_out_len;
    	char	mess_in[256];
    	int	nw,nr;		/* number read and number written */
    	int	nrsf;		/* number read so far, for multiple reads */
    
    	struct sockaddr_in	sin;		 /* socket endpoint */
    
    	pid=getpid();
    	if(argc==2) {
    		name = argv[1];
    		port = WL_PORT;
    	} else if(argc==3) {
    		name = argv[1];
    		port = atoi(argv[2]); // No check for a valid arguement!
    	} else {
    		fprintf(stderr,"ERROR: useage:  %s <name> [<port>]\n", argv[0]);
    		exit(1);
    	}
    	#ifdef DEBUG
    		fprintf(stderr,"DEBUG: %d %s connecting to %s port %d\n", 
    		pid, argv[0], name, port);
    	#endif
    	/* Get the ip address from the domain name. */
    	if((phostent = gethostbyname(name))==0) {
    		fprintf(stderr,"ERROR: %s can not get ip address for %s\n", argv[0], name);
    		exit(1);
    	}
    	#ifdef DEBUG
    		fprintf(stderr,"DEBUG: %d %s hostent.h_addr=%u.%u.%u.%u  hostent.h_length=%d\n", pid, argv[0],
    		(unsigned char)phostent->h_addr[0], 
    		(unsigned char)phostent->h_addr[1], 
    		(unsigned char)phostent->h_addr[2],
    		(unsigned char)phostent->h_addr[3],
    		phostent->h_length);
    	#endif
    
    	/* Get a TCP based socket. */
    	// if((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
    	if((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
    		fprintf(stderr,"ERROR: %s Can't get a socket.\n", argv[0]);
    		exit(1);
    	}
    
    	/* Prepare the endpoint. (Only specify the remote ip address/port) */
    	memset(&sin, 0, sizeof(sin));
    	sin.sin_family = AF_INET;
    	memcpy(&sin.sin_addr, phostent->h_addr, phostent->h_length);
    	sin.sin_port = htons((u_short)port);
    
    
    	/* Make the connection */
    	if(connect(s, (struct  sockaddr  *)&sin, sizeof(sin)) != 0) {
    		fprintf(stderr,"ERROR: %s Can't connect to %s port %d\n", argv[0], name, port);
    		exit(1);
    	}
    
    
    	/* 
    	* Now build and write a message to the server, including the '\0'
    	* messages consist of 1 to 255 bytes.
    	*       the first byte msize = mess[0] is the size of the message,
    	*               including the fisrt byte.
    	*       the bytes mess[1]. mess[2]. ... mess[msize-1] comprise the data
    	*               in the message.
    	*/
    	mess_out_len = strlen(mess_out+1) + 2;
    	sprintf(spid, "%d\0", pid);
    	strncat(mess_out+1, spid, 256-mess_out_len);
    	mess_out_len = strlen(mess_out+1) + 2;
    	mess_out[0] = mess_out_len;
    	
    	#ifdef DEBUG
    		fprintf(stderr,"DEBUG: %d %s write mess_out= %d \"%s\" to socket\n", pid, argv[0], mess_out[0], mess_out+1);
    	#endif
    
    	if((nw=write(s, mess_out, mess_out_len)) != mess_out_len) {
    		fprintf(stderr,"ERROR: %s wrote %d out of %d.\n", argv[0], nw, mess_out_len);
    		exit(1);
    	}
    
    	shutdown(s,1);  /* optional */
    	/* Now read a message of the same size back */
    
    	for(nrsf=0;  nrsf < mess_out_len; nrsf+=nr) {
    		if((nr=read(s, mess_in+nrsf, mess_out_len-nrsf))<=0) {
    			break;
    		}
    		
    		#ifdef DEBUG
    			fprintf(stderr,"DEBUG: %d %s read nr = %d  nrsf = %d\n", pid, argv[0], nr, nrsf);
    		#endif
    	}
    	#ifdef DEBUG
    		fprintf(stderr,"DEBUG: %d %s final nr = %d  nrsf = %d\n", pid, argv[0], nr, nrsf);
    		fprintf(stderr,"DEBUG: %d %s read mess_in = %d \"%s\" from socket\n", pid, argv[0], mess_in[0], mess_in+1);
    	#endif
    
    	/* 
    	* Note the next read should return an EOF, if testing with echo (port=7)
    	* because of the "shutdown(s,1)"
    	*/
    	exit(0);
    }

    Program Output

    Server:
    DEBUG: 17915 ./wld will listen on port 4099
    ERROR: ./wld can not accept connection
    -1
    ERROR: ./wld can not read a message count.

    Client:
    DEBUG: 17921 ./wl connecting to localhost port 4099
    DEBUG: 17921 ./wl hostent.h_addr=127.0.0.1 hostent.h_length=4
    DEBUG: 17921 ./wl write mess_out= 48 "this is a lower case message. from pid = 17921" to socket
    DEBUG: 17921 ./wl final nr = 0 nrsf = 0
    DEBUG: 17921 ./wl read mess_in = 0 "" from socket

  5. #5
    Registered User
    Join Date
    Nov 2007
    Posts
    96
    Also, I just re-compiled with -pedantic flag and received a warning of:

    wld.c:83: warning: pointer targets in passing argument 3 of ‘accept’ differ in signedness

    Could that be causing the issue?

  6. #6
    Registered User
    Join Date
    Nov 2007
    Posts
    96
    I fixed the previous warning but still am having the same issue.

  7. #7
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Radical idea...from the accept man page:
    Quote Originally Posted by man accept
    RETURN VALUE
    On success, accept() returns a non-negative integer that is a descrip‐
    tor for the accepted socket. On error, -1 is returned, and errno is
    set appropriately.
    How about checking the value of errno?

  8. #8
    Registered User
    Join Date
    Nov 2007
    Posts
    96
    Thanks , I have never really been familiar with errno. I am getting a value of 22; how will I see what this value means. I checked online and I believe its for invalid arguments but the man page just provides a list of error returns and not the values.

  9. #9
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by NuNn View Post
    Thanks , I have never really been familiar with errno. I am getting a value of 22; how will I see what this value means. I checked online and I believe its for invalid arguments but the man page just provides a list of error returns and not the values.
    Try strerror.

    However, I believe accept errno 22 is EINVAL, "invalid argument".
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #10
    Registered User
    Join Date
    Nov 2007
    Posts
    96
    Thank you guys, it was indeed "Invalid argument". But now I'm just unsure as to why this is, lol. My guess is that "cin" is never getting set but how would I set this from the client side?

  11. #11
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    you never initialized calen, it must be set to the actual cin size (as it is casted to a more generic address type), so do calen=sizeof(cin) before calling accept() [accept() returns cin filled as output data, but calen is an input]

  12. #12
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    You need to set calen to sizeof(calen) before you call accept.

  13. #13
    Registered User
    Join Date
    Nov 2007
    Posts
    96
    You guys are saviors!!!! Lol, thank you very much now everything is working correctly Have a great day everyone and I'm sure I will be talking with all of you again soon. haha

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Using variables in system()
    By Afro in forum C Programming
    Replies: 8
    Last Post: 07-03-2007, 12:27 PM
  2. [Help] Simple Array/Pointer Program
    By sandwater in forum C Programming
    Replies: 3
    Last Post: 03-30-2007, 02:42 PM
  3. simple silly program
    By verbity in forum C Programming
    Replies: 5
    Last Post: 12-19-2006, 06:06 PM
  4. Simple window program
    By baniakjr in forum C++ Programming
    Replies: 5
    Last Post: 03-11-2006, 03:46 PM
  5. Simple simple program
    By Ryback in forum C++ Programming
    Replies: 10
    Last Post: 09-09-2004, 05:48 AM