在基于TCP连接建立的网络通信中,我们通常习惯用read函数接收数据,用write函数发送数据,这两个函数返回实际接收到的或者发送出去的字节数,在网络不稳定的情况下,我们经常会发现指定发送的数据还未发送完整或者指定接收的数据尚未接收完整,read或者write函数就返回了,通俗的讲就是发送或者接收的数据不完整。在数据量大、网络条件差的情况下尤为明显。对于数据完整度要求严格的通讯协议下,这样的数据丢包就会严重影响程序的性能。那么有没有办法完整的接收或者发送数据呢?答案是肯定的。在此,对read和write函数重新封装一下,得到readn函数和writen函数,顾名思义,readn或者writen函数只有接收或者发送完指定长度的数据方能返回,当然,如果在接收或者发送的过程中连接断开或者不可达了,将返回-1。
函数一:readn——完整的读取数据,成功则返回实际读取的数据长度,失败则返回-1;
int readn(int fd, void *vptr, size_t n) { size_t nleft; ssize_t nread; char *ptr; ptr = (char *)vptr; nleft = n; while (nleft > 0) { if ((nread = read(fd, ptr, nleft)) < 0) { if (EINTR == errno) nread = 0; else return -1; } else if (nread == 0) { break; } nleft -= nread; ptr += nread; } return(n - nleft); }
函数二:writen——完整的发送指定内存区域中的数据,成功则返回实际发送的数据量,失败则返回-1;
int writen(int fd, const void *vptr, size_t n) { size_t nleft; ssize_t nwritten; const char *ptr; ptr = (const char *)vptr; nleft = n; while (nleft > 0) { if ((nwritten = send(fd, ptr, nleft, 0)) <= 0) { if (nwritten < 0 && errno == EINTR) nwritten = 0; else return(-1); } nleft -= nwritten; ptr += nwritten; } return(n); }
除非注明,文章均为CppLive 编程在线原创,转载请注明出处,谢谢。