Thread: simple chat program questions

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    13

    simple chat program questions

    Hey guys, found the forums while searching for anything to help me with my current homework assignment in my C class. This is my 3rd programming class, the previous 2 being in C++ and this in C. I've made it 75% through the semester on my own but I'm stuck and need some help.

    Part 1 of the assignment:

    For this assignment you are going to write a simple chat server. The server is going to accept two client connections and then relay the input data to the other client.
    The server port will be the first command line argument. We will use telnet as the client. It should run until one of the clients starts a line with "quit" ( or the telnet escape character '^]' ). At that point all of the socket must be closed correctly.

    My current code for the server side:
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include <unistd.h>
    #include <string.h>
    
    #define MAGIC_PORT_NUM 15000
    #define BUF_SIZE 512
    
    int main( int argc, char ** argv )
    {
    		char buf1[ BUF_SIZE ];
    		char bytes1;
    		char buf2[ BUF_SIZE ];
    		char bytes2;
    		int rc1;
    		int io_sd1;
    		int io_sd2;
    		int listen_sd;
    		int foo;
    
    		struct protoent * proent_ptr = getprotobyname ( "tcp" );
    		int proto_num = proent_ptr->p_proto;
    		struct sockaddr_in serv;
    		struct sockaddr_in client1;
    		struct sockaddr_in client2;
    		socklen_t cli_len = sizeof( struct sockaddr_in );
    		int port_num = MAGIC_PORT_NUM;
    
    
    		if ( argc > 1 )
    				port_num = atoi( argv[1] );
    
    
    		listen_sd = socket( PF_INET, SOCK_STREAM, proto_num );
    		if ( -1 == listen_sd )
    		{
    				fprintf( stderr, "socket error\n" );
    				exit(1);
    		}
    		printf( "listen_sd = %d\n", listen_sd );
    
    		/* setup the serv sockaddr */
    		serv.sin_family = PF_INET;/* match what socket got */
    		serv.sin_addr.s_addr = htonl( INADDR_ANY );/* network byte order */
    		serv.sin_port = htons( port_num );
    
    		rc1 = bind( listen_sd, (struct sockaddr *)&serv, 
    						sizeof( struct sockaddr_in ) );
    		if ( -1 == rc1 )
    		{
    				fprintf( stderr, "bind error\n" );
    				exit(2);
    		}
    		printf ( "listening on port %d\n", port_num );
    
    		rc1 = listen( listen_sd, 10 );
    		if ( -1 == rc1 )
    		{
    				fprintf( stderr, "listen error\n" );
    				exit(2);
    		}
    		printf ( "listening, waiting on accept\n" );
    
    		/* this blocks waiting for the connect from the client */
    		io_sd1 = accept( listen_sd, (struct sockaddr *)&client1, &cli_len );
    		if ( -1 == io_sd1 )
    		{
    				fprintf( stderr, "client 1 accept error\n" );
    				exit(1);
    		}
    		printf( "io_sd1 = %d\n", io_sd1 );
    
    		io_sd2 = accept( listen_sd, (struct sockaddr *)&client2, &cli_len );
    		if ( -1 == io_sd2 )
    		{
    				fprintf( stderr, "client 2 accept error\n" );
    				exit(1);
    		}
    		printf( "io_sd2 = %d\n", io_sd2 );
    
    
    		/* now we can do IO */
    		/*client 1 read what is typed and send to client2 */
    		/*then client 2 read what is typed and send to client1 */
    		foo = 1;
    		while (foo)
    		{
    				read(io_sd1, buf1, sizeof(buf1));
    				if (strcmp(buf1, "quit\n")==0) 
    				{
    					close( io_sd1 );
    					close( io_sd2 );
    					close( listen_sd );
    				}
    				bytes1 = sprintf ( buf1, buf1);
    				write( io_sd2, buf1, bytes1 );
    
    				read(io_sd2, buf2, sizeof(buf2));
    				if (strcmp(buf2, "quit\n")==0) 
    				{
    					close( io_sd1 );
    					close( io_sd2 );
    					close( listen_sd );
    				}
    				bytes2 = sprintf ( buf2, buf2);
    				write( io_sd1, buf2, bytes2 );
    		}
    
    		return 0;
    }
    My current problem is at the end of the code, both of the clients need to be able to type back and forth to each other indefinitely until one of them types "quit." How can I create a loop to keep going until this happens? My current infinite for loop and strcmp is completely wrong. They don't need to be able to talk at the same time, it's ok if the clients only alternate back and forth in a loop.

    Also, if you can help me figure out how I need to handle this part of the assignment that would be great too:
    "NOTE: When data is sent with telnet each line will end with carriage return and newline ( no NULL ). Send it back that way or it may not display correctly on the client."

    Any help is appreciated. Thanks in advance.

  2. #2
    Registered User
    Join Date
    Sep 2008
    Posts
    27
    Well in your while loop when you check if your buffer is equal to "quit\n" you can add a break statement to exit out of your while loop. However maybe I'm misinterpreting your problem and your looking for a deeper solution.

  3. #3
    Registered User
    Join Date
    Nov 2009
    Posts
    13
    Yeah. How do I perform that check? Basically if buf1 or buf2 are "quit\n" it needs to exit out of the loop or just close the connections.

    Thanks.

  4. #4
    Registered User
    Join Date
    Nov 2009
    Posts
    13
    Would using strstr work for this?

  5. #5
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    603
    Perhaps altering your while loop to be that of a do/while loop instead and base your while loop then with the following

    Code:
    ...
    do
       ...
    
    while (strcmp(quit_buff, "quit\n")!=0)
    I am guessing that it does not matter which buf1 or buf2 gets this quit message first? Perhaps doing a single check, quit_buff, against either streams will suffice here. This will shorten your code down a few steps as well. Then once recieved call all your close()'s.

  6. #6
    Registered User
    Join Date
    Nov 2009
    Posts
    13
    Ok, here's how I solved the close when a user types quit problem for future reference:

    Code:
    		do
    		{
    				read(io_sd1, buf1, sizeof(buf1));
    				bytes = sprintf ( buf1, buf1);
    				write( io_sd2, buf1, bytes );
    				
    				quitTest1 = strstr(buf1,"quit");
    				if (quitTest1 != NULL)
    					break; /* if user types quit, break from loop */
    
    				read(io_sd2, buf2, sizeof(buf2));
    				bytes = sprintf ( buf2, buf2);
    				write( io_sd1, buf2, bytes );
    				
    				quitTest2 = strstr(buf2,"quit");
    				if (quitTest2 != NULL)
    					break; /* if user types quit, break from loop */
    				
    		} while (1);
    
    
    		/* close the connections */
    		  
    		  close( io_sd1 );
    		  close( io_sd2 );
    		  close( listen_sd );
    This closes the program and connections when a user types quit at any time during the conversation. I would prefer if it would close the program when the user types only quit, or starts a line of conversation with the word "quit", but not when typing quit in the middle of a sentence. If that makes sense. Any help is appreciated, thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 02-21-2008, 10:39 AM
  2. Replies: 1
    Last Post: 12-30-2007, 10:08 AM
  3. Simple Socialising Chat Bots
    By bengreenwood in forum C++ Programming
    Replies: 10
    Last Post: 11-28-2007, 08:42 AM
  4. Builder C++ large files support for simple C program
    By Murfury in forum C Programming
    Replies: 3
    Last Post: 11-23-2007, 03:47 PM
  5. Simple Timer, Call external program,
    By bliss in forum C++ Programming
    Replies: 2
    Last Post: 06-02-2005, 11:21 PM

Tags for this Thread