Click here to Skip to main content
12,076,925 members (45,180 online)
Rate this:
 
Please Sign up or sign in to vote.
See more: Linux Sockets
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 8-Feb-11 11:45am

1 solution

Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 1

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()
  Permalink  
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)

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy | Mobile
Web01 | 2.8.160212.1 | Last Updated 9 Feb 2011
Copyright © CodeProject, 1999-2016
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100