讲道理,我们按照默认方式创建的套接字是阻塞访问的,例如我们使用以下方式读阻塞模式的套接字:
"
n = readn(connectfd,buff,MAXLINE);
"
返回值n是一定等于MAXLINE的,否则程序会进入阻塞。
但是在实践过程中,我就是会遇到n不等于MAXLINE,程序依然返回的情况,因此我在这些情况下使用readn代替了read,linux系统没有提供现成的readn供我们调用,因此我们需要自己实现它
"
#include <sys/socket.h>
#include <errno.h>
#include <unistd.h>
int readn(int fd, void *vptr, size_t n)
{
size_t nleft = n; //readn函数还需要读的字节数
ssize_t nread = 0; //read函数读到的字节数
unsigned char *ptr = (char *)vptr; //指向缓冲区的指针
while (nleft > 0)
{
nread = read(fd, ptr, nleft);
if (-1 == nread)
{
if (EINTR == errno)
nread = 0;
else
return -1;
}
else if (0 == nread)
{
break;
}
nleft -= nread;
ptr += nread;
}
return n - nleft;
}
int writen(int fd, const void *vptr, size_t n)
{
size_t nleft = n; //writen函数还需要写的字节数
ssize_t nwrite = 0; //write函数本次向fd写的字节数
const char* ptr = vptr; //指向缓冲区的指针
while (nleft > 0)
{
if ((nwrite = write(fd, ptr, nleft)) <= 0)
{
if (nwrite < 0 && EINTR == errno)
nwrite = 0;
else
return -1;
}
nleft -= nwrite;
ptr += nwrite;
}
return n;
}
"
实际上就是通过轮询保证读到指定的字节数才能返回,可能会对性能造成一定影响,要注意使用场合