TCP 粘包问题处理[1] ( the solution of sticky package problem of TCP )

Because TCP is a stream protocol, so in the translation , there may have lots of sticky bags.

The passage offer two method to solve this problem.

1.We use the fixed length package to solve it.

2. We designed the protocol by ourselves , a struct wiht the head and body of the package. When we receive the message the need to receive the head of the message and then get the body of the package. 


For the first solution:

Server:

/************************************************************************
    > file  name: echoserv.c
    > Author: ma6174
    > Mail: ma6174@163.com 
    > Created Time: Thu 29 Oct 16:38:57 2015
 ************************************************************************/


#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#define ERR_EXIT(m) \
	do \
	{\
		perror(m) ;\
		exit(EXIT_FAILURE) ;\
	}while(0) 



//ssize_t signed integer   size_t unsigned integer  
ssize_t readn ( int fd , void *buf , size_t count )    // encapsulate readn as the function of read 
{
	size_t nleft = count ;
	ssize_t nread ;
	char *bufp ;
	bufp = ( char *) buf ;
	while ( nleft > 0 ) 
	{
		nread = read ( fd , bufp , nleft ) ;
		if( nread  < 0 )
		{	
			if ( errno == EINTR )   // interrupted by signal , we don't think this occasion is not right  
			{
				continue ;
			}
			return -1 ;
		}
		else if ( 0 == nread )    //peer closed  
		{
			return count - nleft ;	
		}
		bufp += nread ;
		nleft -= nread ;
	}
	return  count ;
}


ssize_t writen ( int fd , const void *buf ,size_t count ) 
{
	size_t nleft = count ;
	ssize_t nwritten ;
	char *bufp ;
	bufp = ( char * ) buf ;
	while ( nleft > 0 ) 
	{
		if ( ( nwritten = write ( fd , bufp , nleft ) ) < 0 ) 
		{
			if ( errno == EINTR )  // just like the occasion in writen
			{
				continue ; 
			}		
			return -1 ;
		}
		else if ( 0 == nwritten  ) // if 0 == nread , like nothing happened to write ... 
		{
			continue ;
		}
		bufp += nwritten ;
		nleft -= nwritten ; 
	}
	return count ;
}

void do_service ( int conn ) 
{
	char recvbuf[1024] ;
	while(1) 
	{
		memset ( recvbuf , 0 , sizeof(recvbuf)) ;
		int ret = readn( conn , recvbuf , sizeof(recvbuf) ) ;
		printf ("ret = %d\n" , ret ) ;
		if ( 0 == ret ) 
		{
			printf ("client close") ;
			break ;
		}
		else if ( -1 == ret ) 
		{
			ERR_EXIT ("read") ;
		}
		fputs ( recvbuf , stdout ) ;
		writen ( conn , recvbuf , ret ) ;
	}
}

int 
main () 
{
	int listenfd ;
	if (( listenfd = socket ( PF_INET , SOCK_STREAM , IPPROTO_TCP )) < 0 ) 
	{
		ERR_EXIT("socket") ;
	}
	struct sockaddr_in servaddr ;
	memset ( & servaddr , 0 , sizeof(servaddr ) ) ;
	servaddr.sin_family = AF_INET ;
	servaddr.sin_port = htons (5188) ;
	servaddr.sin_addr.s_addr  = htonl(INADDR_ANY) ;		//INTADDR_ANY == 0

	//other two means to change the host address to network address  
	//servaddr.sin_addr.s_addr = inet_addr("127.0.0.1") ;   
	//inet_aton("127.0.0.1" , &servaddr.sin_addr) ;
	
	/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值