socket编程学习---(四)粘包问题readn writen

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_41572450/article/details/80056866

粘包问题

本质要在应用层维护消息与消息边界问题
1.定长包
2.包尾加\r\n
3.包头加上包体长度(包头定常,比如4字节)
4.更复杂的应用层协议

readn

ssize_t readn(int fd,void *buf,size_t count)
{
    size_t nleft = count; //剩余字节数
    ssize_t nread; //接收到的字节数
    char *bufp = (char *)buf;
    while(nleft > 0)
    {
        if((nread = read(fd,bufp,nleft)) < 0)
          {   if(errno == EINTR)
                   countinue;
               return -1;
          }
         else if(nread == 0) //对方关闭
               return count - nleft; 
         bufp += nread;
         nleft -= nread;
    }
    return count;
}

writen

ssize_t writen(int fd,const 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)
                   countinue;
               return -1;
          }
         else if(nwritten == 0) 
               countinue;
         bufp += nwritten;
         nleft -= nwritten;
    }
    return count;
}

客户端

struct packet{
    int len;  //包头
    char buf[1024];//包体
}

struct packet sendbuf;
struct packet recvbuf;
memset(&sendbuf,0,sizeof(sendbuf));
memset(&recvbuf,0,sizeof(recvbuf));

//这里获得sendbuf.buf.....

int n = strlen(sendbuf.buf);//获得包头
sendbuf.len = htonl(n); 
writen(sock,&sendbuf,4+n);//发送包头包体

int ret = readn(sock,&recvbuf.len,4);
if(ret == -1)
{
     ERR_EXIT("read");
}
else if(ret <4)
{
     printf("cli close");
     break;
}
n = ntohl(recvbuf.len);
ret = readn(sock,recvbuf.buf,n);
if(ret == -1)
{
     ERR_EXIT("read");
}
else if(ret <n)
{
     printf("ser close");
     break;
}
//printf

服务器端

struct packet recvbuf;
memset(&recvbuf,0,sizeof(recvbuf));
int ret = readn(conn,&recvbuf.len,4);
if(ret == -1)
{
     ERR_EXIT("read");
}
else if(ret <4)
{
     printf("cli close");
     break;
}
n = ntohl(recvbuf.len);
ret = readn(conn,recvbuf.buf,n);
if(ret == -1)
{
     ERR_EXIT("read");
}
else if(ret <n)
{
     printf("cli close");
     break;
}
//printf
writen(conn,&recvbuf,4+n);

猜你喜欢

转载自blog.csdn.net/weixin_41572450/article/details/80056866