Thread: select server help

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User Annonymous's Avatar
    Join Date
    Apr 2011
    Location
    Jackson, New Jersey, United States
    Posts
    302

    select server help

    So i wrote a server that incorporates the select function but it is not working properly. I know that I am missing something vital but what? I am trying to make it echo the message from the client back to the client.

    This is the output of the client ->
    Code:
    blah@blah:~/Documents/nix-chat-ui$ ./client 127.0.0.1 12345
    Made a connection to 127.0.0.1
    Message: hey
    server: hey
    Message: hey
    server: hey
    Message: hey
    blah@blah:~/Documents/nix-chat-ui$
    The client closes after 3 calls.




    The output from the asynch server
    Code:
    blah@blah:~/Documents/nix-chat-ui$  ./select 127.0.0.1 12345
    Listening for incoming connections.
    
    
    Select() was successful.
    ./select: New connection from 127.0.0.1 on socket 4
    
    
    Select() was successful.
    Which you can see hangs.


    The server code
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <errno.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    
    int main(int argc, char *argv[]) {
    fd_set master;
    // the temorary fd list for select call
    fd_set read_fds;
    
    struct sockaddr_in serv_addr, cli_addr;
    struct hostent *server;
    int fdmax;
    int i, j;
    FD_ZERO(&master);
    FD_ZERO(&read_fds);
    
    	if((argc < 3) && (argc > 4)) {
    	printf("USAGE: %s + IP Address + Port No.\n", argv[0]);
    	exit(EXIT_FAILURE);
    	}
    
    int debug;
    	if(argc == 4) {
    	debug = atoi(argv[3]);
    	}
    
    /* get the listener */
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    	if(sockfd < 0) {
    	printf("SOCKET(-1) error --> %s.\n", strerror(errno));
    	exit(EXIT_FAILURE);
    	}
    		else if((sockfd) && (debug == 1)) {
    		printf("Successfully created socket.\n");
    		}
    int yes = 1;
    int sockopt = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
    	if(sockopt == -1) {
    	printf("SETSOCKOPT(-1) error --> %s.\n", strerror(errno));
    	exit(EXIT_FAILURE);
    	}
    		else if((sockopt) && (debug == 1)){
    		printf("Setsockopt() was successful.\n");
    		}
    
    server = gethostbyname(argv[1]); 
    	if(server == NULL) {
    	printf("GETHOSTBYNAME(NULL) error --> %s.\n", strerror(errno));
    	exit(EXIT_FAILURE);
    	}
    
    		else if((server) && (debug == 1)) {
    		printf("Successfuly got host by name.\n");
    		}
    
    int portno = atoi(argv[2]);
    	if(portno < 0) {
    	printf("ATOI(-1) error --> %s.\n", strerror(errno));
    	exit(EXIT_FAILURE);
    	}
    
    	if((portno == 0) && (debug == 1)) {
    	printf("ATOI(0) - DEBUG MSG --> %s.\n", strerror(errno));
    	}
    
    	if((portno) && (debug == 1)) {
    	printf("Successfully binded to port %d.\n", portno);
    	}
    
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    //memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
    serv_addr.sin_port = htons(portno);
    memset(&(serv_addr.sin_zero), '\0', 8);
    
    int binder = bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
    	if(binder < 0) {
    	printf("BIND(-1) error --> %s.\n", strerror(errno));
    	exit(EXIT_FAILURE);
    	}
    
    	if((binder == 0) && (debug == 1)) {
    	printf("BIND(0) - DEBUG MSG --> %s.\n", strerror(errno));
    	}
    	
    	if((binder) && (debug == 1)) {
    	printf("Bind was successful.\n");
    	}
    
    int listener = listen(sockfd, 10);
    	if(listener < 0) {
    	printf("Listen(-1) error --> %s.\n", strerror(errno));
    	exit(EXIT_FAILURE);
    	}
    
    	if((listener == 0) && (debug == 1)) {
    	printf("LISTEN(0) - DEBUG MSG --> %s.\n", strerror(errno));
    	}
    		else {
    		printf("Listening for incoming connections.\n");
    		 if((listener) && (debug == 1)) {
    		 printf("Entering main loop.\n");
    		 }
    		}
     
    FD_SET(sockfd, &master);
    //Watch the current FD.
    fdmax = sockfd; 
    
    for( ; ; ) {
    read_fds = master;
    char buffer[4096];
    
    int selector = select(fdmax+1, &read_fds, NULL, NULL, NULL);
    	if(selector < 0) {
    	printf("SELECT(-1) error --> %s.\n", strerror(errno));
    	exit(EXIT_FAILURE);
    	}
    
    		else {
    		printf("\n\nSelect() was successful.\n");
    		}
    
    // Run through the existing connections looking for data to be read
    for(i = 0; i <= fdmax; i++) {
    	if(FD_ISSET(i, &read_fds)) { 
    
    	if(i == sockfd) {
    	 if(debug == 1) {
    	 printf("i == sockfd DEBUG MSG --> %s.\n", strerror(errno));
    	 }
    
    	socklen_t clilen;
    	clilen = sizeof(cli_addr);
    
    	int newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
    	if(newsockfd < 0) {
    	printf("Accept(-1) error --> %s.\n", strerror(errno));
    	exit(EXIT_FAILURE);
    	}
    
    	if((newsockfd == 0) && (debug == 1)) {
    	printf("ACCEPT(0) - DEBUG MSG --> %s.\n", strerror(errno));
    	}
    
    		else {
    		 if(debug == 1) {
    		 printf("Accept(1) was successful.\n");
    		 }
    
    		 // Add new FD to masterset.
    		 FD_SET(newsockfd, &master); 
    		 
    		 if(debug == 1) {
    		 printf("newsockfd == %d\n", newsockfd);
    		 printf("fdmax == %d\n", fdmax);
    		 }
    
    		 if(newsockfd > fdmax) { 
    		  if(debug == 1) {
    		  printf("newsockfd > fdmax.\n");
    		  printf("fdmax == newsockfd.\n");
    		  }
    
    		 fdmax = newsockfd;
    		 } 
    
    		 if((newsockfd < fdmax) && (debug == 1)) {
    		 printf("newsockfd < fdmax.\n");
    		 }
    
    		 if((newsockfd == fdmax) && (debug == 1)) {
    		 printf("newsockfd == fdmax.\n");
    		 }
    
    		printf("%s: New connection from %s on socket %d\n", argv[0], inet_ntoa(cli_addr.sin_addr), newsockfd);
    		}
    	}
    
    		else { // Start of read loop
    		ssize_t bytes_read = recv(i, buffer, sizeof(buffer), 0);
    		 if(bytes_read <= 0) {
    
    		 if(bytes_read < 0) {
    		 printf("RECV(-1) error --> %s.\n", strerror(errno));
    		 exit(EXIT_FAILURE);
    		 }
    
    		 if(bytes_read == 0) {
    		 // Connection closed by remote host
    		 printf("%s: socket %d hung up\n", argv[0], i);
    		 }
    
    		 FD_CLR(i, &master);
    		 close(i);
    		}
    
    		else { // Start of inner read loop if true
    		 if((bytes_read) && (debug == 1)) {
    		 printf("Recieve was successful.\n");
    		 }
    
    		 FD_CLR(i, &master);
    		 close(i);
    
    		for(j = 0; j <= fdmax; j++) { // Start of inner for loop to send data
    		// Echo message to all
    		if(FD_ISSET(j, &read_fds)) {
    
    		 if(debug == 1) {
    		 printf("j is in the masterset.\n");
    		 }
    
    		if((j == sockfd) && (debug == 1)) {
    		printf("j == sockfd DEBUG MSG --> %s.\n", strerror(errno));
    		}
    
    		if((j != sockfd) && (debug == 1)) {
    		printf("j != sockfd DEBUG MSG --> %s.\n", strerror(errno));
    		}
    
    		if((j == i) && (debug == 1)) {
    		printf("j == i DEBUG MSG --> %s.\n", strerror(errno));
    		}
    
    		if((j != i) && (debug == 1)) {
    		printf("j != i DEBUG MSG --> %s.\n", strerror(errno));
    		}
    
      		// Except the listener and ourselves 
    		  if((j != sockfd) && (j != i)) {
    		   if(debug == 1) {
    		   printf("j != sockfd && j != i");
    		   }
    
      	  	  ssize_t bytes_written = send(j, buffer, bytes_read, 0);
    		  if(bytes_written < 0) {
      	  	  printf("WRITE(-1) error --> %s.\n", strerror(errno));
    		  }
    
    		  if((bytes_written == 0) && (debug == 1)) {
    		  printf("WRITE(0) - DEBUG MSG --> %s.\n", strerror(errno));
    		  }
    
    		  if((bytes_written) && (debug == 1)) {
    		  printf("WRITE(1) was successful.\n");
    		  }
    
      		 }
    		}
    		} // End of inner for loop to send data
    		} // Inner read if read > 0
    	} // End of read loop
    	}
    	}
    }
    
    return 0;
    }
    I am sure the client is good. I have written many of them and they work with my regular synchrous servers but I'll post the client code anyway.

    The client
    Code:
    #include <stdio.h> 
    #include <string.h> 
    #include <stdlib.h> 
    #include <unistd.h> 
    #include <sys/socket.h> 
    #include <sys/types.h> 
    #include <netdb.h> 
    #include <netinet/in.h> 
    #include <arpa/inet.h>
    #include <errno.h>
    
    int main(int argc, char *argv[]) {  
    struct hostent *server; 
    struct sockaddr_in serv_addr/*, cli_addr*/;
    
    	if((argc < 3) && (argc > 4)) {
    	fprintf(stderr, "Ussage: %s + IP Address + port No. Append a 1 to turn verbose on.\n", argv[0]);
    	exit(EXIT_FAILURE);
    	}
    
    int debug;
    	if(argc == 4) {
    	debug = atoi(argv[3]);
    	}
    
    
    int sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    	if(sockfd < 0) {
    	printf("SOCKET(-1) error ---> %s.\n", strerror(errno));
    	exit(EXIT_FAILURE);
    	}
    
    	if((sockfd == 0) && (debug == 1)) {
    	printf("SOCKET(0) error ---> %s.\n", strerror(errno));
    	}
    
    	if((sockfd) && (debug == 1)) {
    	printf("DEBUG MSG --> SOCKET was successful.\n");
    	}
    
    int yes = 1; 
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
    
    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    server = gethostbyname(argv[1]); 
    	if(server == NULL) {
    	fprintf(stderr, "No such host.\n");
    	printf("%s\n", strerror(errno)); 
    	exit(EXIT_FAILURE);
    	}
    
    		else if((server) && (debug == 1)) {
    		printf("DEBUG MSG - Successfully got host by name.\n");
    		}
    
    int portno = atoi(argv[2]);
    	if(portno < 0) {
    	printf("PORTNO(0) error ---> %s.\n", strerror(errno));
    	}
    
    	if((portno == 0) && (debug == 1)) {
    	printf("DEBUG MSG - ATOI(0) error ---> %s.\n", strerror(errno));
    	}
    
    	if((portno) && (debug == 1)) {
    	printf("Successfully binded to port %d.\n", portno);
    	}
    
    serv_addr.sin_family = AF_INET;
    memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length); 
    serv_addr.sin_port = htons(portno);
    
    int connector = connect(sockfd, (const struct sockaddr *)&serv_addr, sizeof(serv_addr));
    	if(connector < 0) { 
    	fprintf(stderr, "%s. CONNECT()\n", strerror(errno));
    	exit(EXIT_FAILURE);
    	}
    
    		else {
    		printf("Made a connection to %s\n", inet_ntoa(serv_addr.sin_addr)); 
    		}
    
    for( ; ; )
    {
    char buffer[4096];
    
    printf("Message: ");
    fgets(buffer, sizeof(buffer), stdin);
    ssize_t bytes_written = write(sockfd, buffer, strlen(buffer));
    	if(bytes_written < 0) { 
    	printf("WRITE(-1) error ---> %s.\n", strerror(errno));
    	}
    
    	if(bytes_written == 0) {
    	//printf("WRITE(0) error ---> %s.\n", strerror(errno));
    	printf("Nothing was written.\n");
    	}
    
    	if((bytes_written) && (debug == 1)) { 
    	printf("DEBUG MSG - WRITE was successful.\n");
    	}
    
    ssize_t bytes_read = read(sockfd, buffer, sizeof(buffer));
    	if(bytes_read < 0) {
            //fprintf(stderr, "Error reading message from %s\n", inet_ntoa(cli_addr.sin_addr));
            printf("READ(-1) error ---> %s.\n", strerror(errno));
            exit(EXIT_FAILURE);
            }
    
    	//Test to see if the buffer is blank.
            if((bytes_read == 0) && (debug == 1)) {
            printf("READ(0) error ---> %s.\n", strerror(errno));
            }
    		else {
    		printf("server: %s", buffer);
    		}
    
    }
    
    close(sockfd);
    
    return 0;
    }
    I am missing some parameters to the read/recv calls or do I need to enable non-blocking mode??
    Last edited by Annonymous; 10-14-2012 at 10:58 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Chat server not using select
    By Per Andersson in forum C Programming
    Replies: 1
    Last Post: 07-06-2012, 08:12 AM
  2. TCP Server with select() function
    By netpumber in forum Windows Programming
    Replies: 6
    Last Post: 10-24-2011, 10:19 AM
  3. Select(); server help!
    By klipseracer in forum Networking/Device Communication
    Replies: 3
    Last Post: 03-02-2008, 11:16 PM
  4. Running two UDP server simultaneously using select()
    By PiJ in forum Networking/Device Communication
    Replies: 15
    Last Post: 01-31-2008, 10:49 AM
  5. select() server
    By chrismiceli in forum Linux Programming
    Replies: 0
    Last Post: 09-09-2003, 08:56 PM

Tags for this Thread