Click here to Skip to main content
15,886,799 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello,
Can someone please look at the code below and tell me what I am missing here.

Below is a simple tcp client code that opens a TCP connection with a server and sends a constant message in a loop. The code works fine as far as establishing the connection and sending the message. The problem I have is error handling:
When the program starts running and if the connection is established, it starts sending the messages. I then purposely close the server in the middle before the client finishes all the messages to see how does it handle the error (check error code returned by send() function). I was surprised that after I shutdown the server program, the function returns success code for the first attempt after the server is closed. On the second attempt the client crashes (Linux terminates the program and I get the shell prompt back).

Why does not send function return error code?. Why does Linux terminates the program?. How do I do a robust error checking then ?.

Please note that running the same code under windows behaves as I expected (proper error codes are returned). Please advice.
//Performs a delay
int Delay (int milliseconds)
{
	struct timespec timeOut,remains;

	timeOut.tv_sec = milliseconds /MILLI;
	timeOut.tv_nsec = (milliseconds - timeOut.tv_sec*MILLI) * 1000000;
	if (nanosleep(&timeOut, &remains) == -1)
	{
		return timeOut.tv_sec *MILLI + timeOut.tv_nsec /1000000;
	}

	return 0;
}
/*----------------------------------------------------------------*/
//Connect to the server and send constant messages
int StartConnection()
{
	char ipaddress[] = "192.168.100.20";
	int port = 1234;
	struct sockaddr_in sa;
	int sock;

	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		perror("unable to create server socket");
		return -1;
	}

	memset(&sa, 0, sizeof(sa));
	sa.sin_family      = AF_INET;
	sa.sin_port	   = htons((USHORT)port);
	sa.sin_addr.s_addr = inet_addr(ipaddress);

	cout << "Connecting to " << ipaddress << ":" << port << endl;

	if (connect(sock,(SOCKADDR*)&sa,sizeof(sa)) < 0)
	{
		perror ("Error connecting");
		return -1;
	}

	cout << "Connection established" << endl;

	char data[]="Sample data\n";
	int count = 10;
	int delay = 1000;

	for (int i =0; i< count ; i++ )
	{
		cout << "Delaying " << delay/1000 \
                     << " seconds before sending data ("  \
                     << i+1 << " of " << count << ") ...";

		Delay(delay);
		int result=send(sock,(char*)data,sizeof(data),0);
		if (result > 0)
		        cout << "success" << endl;
		else
		{
                        //This is where my problem is
                        //It never returns error code
                        // when server shutsdown nt the middle
			perror ("error");
		}
	}

	cout << "All done" << endl;

	return 0;
}
Posted

1 solution

Linux raises a SIGPIPE signal when you try to write to a closed socket, this causes your program to terminate. You need to either capture and handle the signal or disable it by using the MSG_NOSIGNAL flag in send(). See the man pages for send(), sigaction() and socket()
 
Share this answer
 
Comments
Member 4211040 9-Feb-11 11:57am    
Thanks a lot. It makes sense now.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900