954,498 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Tcp socket send help

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 ??

srinivasjinde
Light Poster
31 posts since Nov 2009
Reputation Points: 10
Solved Threads: 0
 

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.

srinivasjinde
Light Poster
31 posts since Nov 2009
Reputation Points: 10
Solved Threads: 0
 

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.

L7Sqr
Practically a Master Poster
657 posts since Feb 2011
Reputation Points: 201
Solved Threads: 124
 

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

srinivasjinde
Light Poster
31 posts since Nov 2009
Reputation Points: 10
Solved Threads: 0
 

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

L7Sqr
Practically a Master Poster
657 posts since Feb 2011
Reputation Points: 201
Solved Threads: 124
 

*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
//============================================================================
srinivasjinde
Light Poster
31 posts since Nov 2009
Reputation Points: 10
Solved Threads: 0
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: