TCP是字节流,无边界的协议。UDP是传的报文,是有边界的。所以TCP会产生粘包问题
具体原因:
1.由于程序write进套接字缓冲区时将一段完整的消息分开了,此时会造成粘包。
2.由于TCP协议有MSS的限制,可能会产生分段,所以会产生粘包。
3.由于IP协议有MTU的限制,可能会进行分片,所以会产生粘包。
解决方案:
应用层自己维护消息与消息的边界。
1.定长包
2.包尾加\r\n
3.包头加上包体长度
4.更复杂的应用层协议
下面我们封装两个函数实现定长包:
ssize_t readn(int fd,void *buf,size_t count)//封装读函数,将其封装为read一样的形式
{
size_t nleft = count;//剩余的字节数
ssize_t nread;//表示接受了的字节数
char *bufp = (char*)buf;
while(nleft > 0)
{
if( (nread=read(fd,bufp,nleft)) < 0 )
{
if(errno == EINTR)
continue;
return -1;
}
else if(nread == 0)
return count - nleft;
bufp += nread;
nleft -= nread;
}
return count;
}
ssize_t writen(int fd,void *buf,size_t count)//同理
{
size_t nleft = count;//剩余的字节数
ssize_t nwritten;//表示写入了的字节数
char *bufp = (char*)buf;
while(nleft > 0)
{
if( (nwritten=write(fd,bufp,nleft)) < 0 )
{
if(errno == EINTR)
continue;
return -1;
}
else if(nwritten== 0)
continue;
bufp += nwritten;
nleft -= nwritten;
}
return count;
}