C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 11-04-2009, 05:46 PM   #1
Registered User
 
Join Date: Nov 2009
Posts: 7
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.
surefire is offline   Reply With Quote
Old 11-04-2009, 11:47 PM   #2
Registered User
 
Join Date: Sep 2008
Posts: 24
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.
Albinoswordfish is offline   Reply With Quote
Old 11-05-2009, 11:32 AM   #3
Registered User
 
Join Date: Nov 2009
Posts: 7
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.
surefire is offline   Reply With Quote
Old 11-05-2009, 11:36 AM   #4
Registered User
 
Join Date: Nov 2009
Posts: 7
Would using strstr work for this?
surefire is offline   Reply With Quote
Old 11-05-2009, 12:09 PM   #5
Registered User
 
slingerland3g's Avatar
 
Join Date: Jan 2008
Location: Seattle
Posts: 476
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.
slingerland3g is offline   Reply With Quote
Old 11-05-2009, 08:16 PM   #6
Registered User
 
Join Date: Nov 2009
Posts: 7
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.
surefire is offline   Reply With Quote
Reply

Tags
chat, client, loop, server, socket

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
This is a simple program.. Help me please I think it has an error.. lesrhac03 C Programming 4 02-21-2008 10:39 AM
Please help me to convert a simple C++ program into an object-oriented one. zekesteer C++ Programming 1 12-30-2007 10:08 AM
Simple Socialising Chat Bots bengreenwood C++ Programming 10 11-28-2007 08:42 AM
Builder C++ large files support for simple C program Murfury C Programming 3 11-23-2007 03:47 PM
Simple Timer, Call external program, bliss C++ Programming 2 06-02-2005 11:21 PM


All times are GMT -6. The time now is 03:45 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22