In a client server program ... generally when the server goes down the client on executing the send command 2 times returns a SIGPIPE signal . I want to know y this happens. The client must recieve sigpipe immediately when it sends a message after the socket connection is broken . I have tried many versions of client server programs , when i close the server down , client after it sends 2 messages only is it able to receive a sigpipe signal, shouldn't it be like the cleint receives sigpipe immediately after it sends any msg ??

Recommended Answers

All 5 Replies

I am basically handling this signal and making the client reconnect to the server (server rebootes after it goes down) . As long as I dont receive a sigpipe signal i wouldnt know that the pipe is broken.

Also Is there any other way in which the client can detect that the server has gone down. It must detect immediately that the connection is broken and try to reconnect with the server.

The nice thing about TCP is that it manages so much for you under the hood. The problem with TCP is that it manages so much for you under the hood. There is the possibility, due to the send window, that you can have data sent by the client and not received by the server that encompasses several messages. It is due to this situation that your send calls are not blocking [1]. What is likely happening is that you have the first message queued by the OS before there is a notification that the remote end was down and only on the second send do you see the error.

[1] Notice that when I say non-blocking I mean with regard to the local buffer. Depending on how you set up your connection the send would actually block if your local buffer was full.

So how do I make a change such that I receive the signal immediately after I send 1st message??

Depending on your situation, you may not be able to.

*What is likely happening is that you have the first message queued by the OS before there is a notification that the remote end was down and only on the second send do you see the error.

when i send msgs before the pipe is broked, the OS sends them immediately , then y is it queuing the 1st msg when the socket is broken??
See if u can find a way around this..
the client and server code is ..

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <memory.h>
#include <errno.h>
#include <signal.h>

using namespace std;


int MAXLEN=1024;
int PORT=20000;

void sigHlr(int sigNo)
{
	cout << "SIGNAL Received " << sigNo;
}

main( int argc, char *argv[])
{
	struct sockaddr_in serv;
	int sockfd,newsockfd;
	char mesg[MAXLEN];
	char reply[MAXLEN];
	int port = PORT;

	signal(SIGPIPE, sigHlr);	
	if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
	{
		cout << "client : socket error.\n";
		exit(1);
	}
	bzero((char *)&serv,sizeof(serv));
	
	serv.sin_family = AF_INET;
	serv.sin_addr.s_addr = inet_addr("127.0.0.1");
	serv.sin_port = htons(port);
	
	if( argc == 2 )
	{
		serv.sin_addr.s_addr = inet_addr("127.0.0.1");
		port = atoi(argv[1]);
		serv.sin_port = htons(port);
		
	}
	
	else if ( argc == 3 )
	{
		serv.sin_addr.s_addr = inet_addr(argv[2]);
		port = atoi(argv[1]);
		serv.sin_port = htons(port);
	}
	
	if ( connect(sockfd,(struct sockaddr *)&serv,sizeof(serv)) < 0)
	{
		cout << "client : connect error.\n";
		exit(1);
	}

	cout << "Client connected to server successfully at port:" << port << endl;

	while(1)
	{
		cout << endl << "Enter message to server : (Enter q to quit)" << endl;
		cin.getline(mesg,MAXLEN,'\n');
	
		if( strcmp(mesg,"q") == 0 )
		{
			close(sockfd);
			break;
		}
		cout << "Message sending is: " << mesg <<endl;
		if ( send(sockfd,mesg,strlen(mesg)+1,0) < 0  || errno == -1 )
		{
			perror("send");
			//close(sockfd);
			//exit(1);
			
			// for implementing redundancy at MMI client
			sleep(10);
				if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
				{
					cout << "client : socket error.\n";
					exit(1);
				}
				bzero((char *)&serv,sizeof(serv));
				
				serv.sin_family = AF_INET;
				serv.sin_addr.s_addr = inet_addr("127.0.0.1");
				serv.sin_port = htons(port);
				
				if( argc == 2 )
				{
					serv.sin_addr.s_addr = inet_addr("127.0.0.1");
					port = atoi(argv[1]);
					serv.sin_port = htons(port);
					
				}
				
				else if ( argc == 3 )
				{
					serv.sin_addr.s_addr = inet_addr(argv[2]);
					port = atoi(argv[1]);
					serv.sin_port = htons(port);
				}
				
				if ( connect(sockfd,(struct sockaddr *)&serv,sizeof(serv)) < 0)
				{
					cout << "client : connect error.\n";
					exit(1);
				}
		}
/*
		if ( recv(sockfd,&reply,MAXLEN,0) < 0 )
		{
			perror("recv");
			close(sockfd);
			exit(1);
		}
		cout << endl << "client: Received message " << endl;
		cout << "Message is : " << reply <<endl;
*/
	}
	close(sockfd);
}


//============================================================================
// End of tcpClient.cpp
//============================================================================

server:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/errno.h>

using namespace std;

int STRLEN = 1024;	
int PORT = 20000;


int main( int argc, char *argv[])
{
	int sockfd;	
	int newsockfd;
	int clilen;
	struct sockaddr_in serv,cli;
	int chpid;
	char buf[STRLEN],ack[STRLEN];
	int port = PORT;

	if ( argc == 2 )
	{
		port = atoi(argv[1]);
	}

	if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
	{
		perror("socket");
		exit(0);
	}

	bzero((char *)&serv,sizeof(serv)) ;

	serv.sin_family = AF_INET;
	serv.sin_addr.s_addr = htonl(INADDR_ANY);
	serv.sin_port = htons(port);

	if (bind(sockfd,(struct sockaddr *)&serv,sizeof(serv)) < 0)
	{
		perror("bind");
		exit(1);
	}

	listen(sockfd,5);

	while (1)
	{
		clilen = sizeof(cli);
		cout << "Server waiting for connection request from client " << endl;
		if ( (newsockfd = accept(sockfd,(struct sockaddr *)&cli,(socklen_t *)&clilen)) < 0 )
		{
			perror("accept");
			close(sockfd);
			exit(1);
		}
		cout << "server : accepted connection from client  at port: " << cli.sin_port <<endl;
		
		if( (chpid = fork()) == 0 )
		{
			//Child Process
			//Handle request and exit
			cout << "I am child process on server .. I reply for your request " << endl;
			close(sockfd);
			while ( recv(newsockfd,&buf, STRLEN, 0) > 0 )
			{
				cout << endl << "server : received message " <<endl;
				cout << "Message is :" << buf << endl;	
				sprintf(ack,"%s ACK",buf);
				cout << endl << "server sending message to client" << endl;
				cout << "Message is :" << ack << endl;
				if ( send(newsockfd,ack,strlen(ack)+1,0) < 0 )
				{
					perror("send");
					close(newsockfd);
					exit(1);
				}
			}
			close(newsockfd);
			cout << "Child is exiting" << endl;
			exit(1);
		}
	
		else if(chpid < 0 )
		{
			cout << "Fork error\n";
			exit(1);
		}
		else
		{
			//Parent process
			close(newsockfd);
		}
	}

}

//============================================================================
// End of tcpServer.cpp
//============================================================================
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.