Re: problem with socket read( ) on TCP server side

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I tried with a single client-server also , but the same problem exists.
write() to the socket on client's side is returning the number of
bytes written correctly, but on server side read( ) remains in blocked
state.

Again ACK is sent from the server side for the data , but the data is
not reaching the server process.

Attached are the source files -  client.c , server.c and lib.c has
some common function definitions.

On Sat, Oct 10, 2009 at 2:26 PM, Gao Free_Wind <gfree.wind@xxxxxxxxx> wrote:
> Please show your source codes.
> And i could give your some advices here.
> 1. Debug with one client, only use your 1st client;
> 2. Check the return value when 1st client send data to server.
>
> On Sat, Oct 10, 2009 at 4:34 PM, chandan apsangi <chandan.apsangi@xxxxxxxxx>
> wrote:
>>
>> Hi,
>>
>> I was trying out a simple client - server program using Linux sockets.
>> Server basically echoes back whatever it receives from the client.
>> Server is multi threaded to handle multiple client requests.
>> All clients and server are running on the same system - localloop
>>
>> The problem i'm facing is that -
>> Whatever the 1st client writes to the socket is not being read on the
>> server side child process for that connection.
>> For all the subsequent client - server connections , server is able to
>> read and write back whatever is read.
>>
>> And one more info:
>>
>> I used wireshark to see what is happening - and connection is being
>> established properly (3 way exchange) for all the clients.
>> Also, the server is sending ACK for the 1st client's data, but this
>> data is not reaching the server process connected with that client.
>> For all subsequent client's the packet exchange is proper.
>>
>> Anything wrong I may be doing here?
>>
>> Thanks,
>> Chandan
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-net" in
>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
#include "unp.h"

int main(int argc,char *argv[])
{
	int sockfd,n;
	struct sockaddr_in servaddr;
	socklen_t servlen;
	

	if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
		write_error("socket error");

	bzero(&servaddr,sizeof(servaddr));

	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(SERV_PORT);
	if( (n = inet_pton(AF_INET, argv[1], &servaddr.sin_addr)) <= 0)
	{
		if(n < 0)
			write_error("inet_pton failed");
	
		else
			printf("inet_pton failed, no errno\n");
			exit(1);
	}
	
	servlen = sizeof(servaddr);
	if( connect(sockfd,(struct sockaddr *)&servaddr,servlen) < 0)
		write_error("connect error");

	str_cli(stdin,sockfd);

	exit(0);
}

void str_cli(FILE *fp,int sockfd)
{

	char sendline[MAXLINE] , recvline[MAXLINE];

	while(Fgets(sendline,MAXLINE,fp) != NULL)
	{
		printf("got the newline\n");
		Writen(sockfd,sendline,strlen(sendline));
		printf("written to socket\n");
		if(Readline(sockfd,recvline,MAXLINE) <= 0)
		{	
			printf("str_cli : Readline prematurely quit\n");
			exit(1);
		}
		printf("writing to output\n");

/*
    char line[100];

    int bytes_read;


    bytes_read = recv(sockfd, line, sizeof(line), 0);

    send(sockfd, line, bytes_read, 0);	
*/	
    Fputs(recvline,stdout);
	
	}
}
		
	

#include "unp.h"

int main()
{
	int listenfd, connfd;
	pid_t chpid;
	socklen_t clilen;
	struct sockaddr_in servaddr, cliaddr;
	
	listenfd = socket(AF_INET,SOCK_STREAM,0);
	
	if(listenfd < 0)
	{
		write_error("error while creating socket");	
	}

	bzero(&servaddr,sizeof(servaddr));
	bzero(&cliaddr,sizeof(cliaddr));

	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(SERV_PORT);
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	
	if(bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0)
	{
		write_error("error binding the socket");
	}


	if(listen(listenfd,LISTENQ) < 0)
	{	
		write_error("error listen()");
	}

	printf("server listening\n");

	clilen = sizeof(cliaddr);
	printf("server to accept\n");
	if(connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&clilen) < 0)
		{
/*			if(errno == EINTR)
			//	continue;

			else
				write_error("accept failed");*/
			exit(0);
		}
	printf("server accepted\n");


	str_echo(connfd);
	
	if(close(connfd) == -1)
		write_error("close failed");
}

void str_echo(int sockfd)
{
	ssize_t n;
	char line[MAXLINE];
	printf("inside str_echo\n");	
	for(;;)
	{
		if((n = Readline(sockfd,line,MAXLINE)) == 0)
			return;
		
		printf("calling writen: %d",n);
		Writen(sockfd,line,n);
	}
    
/*    char line[100];

    int bytes_read;
	int done = 0;

	while(!done)
	{
	    bytes_read = recv(sockfd, line, sizeof(line), 0);
		if(bytes_read > 0)
			done = 1;
	    send(sockfd, line, bytes_read, 0);
	}*/
}

#include "unp.h"
		
ssize_t Readline(int fd,void *ptr, size_t maxlen)
{
	ssize_t n;
	
	if( ( n = readline(fd,ptr,maxlen)) < 0 )
		write_error("readline error");

/*	if((n = recv(fd,ptr,maxlen,0)) < 0)
		write_error("recv error");
*/
	return n;
}


static ssize_t
my_read(int fd, char *ptr)
{
	static int	read_cnt = 0;
	static char	*read_ptr;
	static char	read_buf[MAXLINE];

	if (read_cnt <= 0) {
again:
		if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {
			if (errno == EINTR)
				goto again;
			return(-1);
		} else if (read_cnt == 0)
			return(0);
		read_ptr = read_buf;
	}

	read_cnt--;
	*ptr = *read_ptr++;
	return(1);
}

ssize_t
readline(int fd, void *vptr, size_t maxlen)
{
	int		n, rc;
	char	c, *ptr;

	ptr = vptr;
	for (n = 1; n < maxlen; n++) {
		if ( (rc = my_read(fd, &c)) == 1) {
			*ptr++ = c;
			if (c == '\n')
				break;	/* newline is stored, like fgets() */
		} else if (rc == 0) {
			if (n == 1)
				return(0);	/* EOF, no data read */
			else
				break;		/* EOF, some data was read */
		} else
			return(-1);		/* error, errno set by read() */
	}

	*ptr = 0;	/* null terminate like fgets() */
	return(n);
}
/* end readline */



void Writen(int fd, void *ptr, size_t nbytes)
{
	
	if(writen(fd,ptr,nbytes) != nbytes)
		write_error("writen error");

//	send(fd,ptr,nbytes,0);
}

ssize_t writen(int fd, const void *vptr, size_t n)
{
	const char *ptr = vptr;
	size_t nleft = n;
	ssize_t nwritten;
	printf("writen()\n");
	while(nleft > 0)
	{
		if( (nwritten = write(fd,ptr,nleft)) <= 0 )
		{
			if(errno == EINTR)
				nwritten = 0;
			
			else
				return -1;
		}
		printf("written %d bytes",nwritten);
		nleft -= nwritten;
		ptr += nwritten;
	}
	return n;
}

void write_error(char *err)
{
	printf("write_error()\n");
	/*char *errstr = strerror(errno);
	strcat(errstr,"\t");
	strcat(errstr,err);*/
	strcat(err,"\0");
	printf("%s",err);
	exit(1);
}

void Fputs(const char *line, FILE *stream)
{
	if(fputs(line,stream) == EOF)
		write_error("fputs error");
}

char* Fgets(char *ptr, int n , FILE *stream)
{
	char *rptr;
	if((rptr = fgets(ptr,n,stream)) == NULL && ferror(stream))
		write_error("fgets error");

	return rptr;
}

void sig_chld(int signo)
{
	pid_t pid;
	int stat;

	while( ( pid = waitpid(-1,&stat,WNOHANG) ) > 0 )
		printf("child terminated %d\n",pid); 

	return;
}

Sigfunc *
signal(int signo, Sigfunc *func)
{
	struct sigaction	act, oact;

	act.sa_handler = func;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	if (signo == SIGALRM) {
#ifdef	SA_INTERRUPT
		act.sa_flags |= SA_INTERRUPT;	/* SunOS 4.x */
#endif
	} else {
#ifdef	SA_RESTART
		act.sa_flags |= SA_RESTART;		/* SVR4, 44BSD */
#endif
	}
	if (sigaction(signo, &act, &oact) < 0)
		return(SIG_ERR);
	return(oact.sa_handler);
}
/* end signal */

Sigfunc *
Signal(int signo, Sigfunc *func)	/* for our signal() function */
{
	Sigfunc	*sigfunc;

	if ( (sigfunc = signal(signo, func)) == SIG_ERR)
		write_error("signal error");
	return(sigfunc);
}

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux