Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: Linux socket
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 at 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
0 OriginalGriff 195
1 ProgramFOX 130
2 Maciej Los 105
3 Sergey Alexandrovich Kryukov 85
4 Afzaal Ahmad Zeeshan 82
0 OriginalGriff 6,564
1 Sergey Alexandrovich Kryukov 6,048
2 DamithSL 5,228
3 Manas Bhardwaj 4,717
4 Maciej Los 4,150


Advertise | Privacy | Mobile
Web03 | 2.8.1411022.1 | Last Updated 9 Feb 2011
Copyright © CodeProject, 1999-2014
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