字节流套接口的读写
字节流套接口上的read和write函数的使用与普通的I/O操作不同。由于内核中套接口的缓冲区是一个有限的空间,当这个缓冲空间不足以存储你要接收或发送的数据时,函数返回的字节数就会比预期发送的字节数少。这时,再次把剩余的数据操作一次即可。
为了预防缓冲区空间不足的情况,可以调用readn、writen、readline、writelin函数
readn函数:从一个描述字读n个字节
// return readn number ssize_t readn(int fd, void* vptr, size_t n) { size_t nleft; size_t nread; char* ptr; ptr = vptr; nleft = n; while(nleft > 0){ if((nread = read(fd, vptr, nleft)) < 0){ if(errno == EINTR) //由于信号中断,没读成功任何数据 nread = 0; else return -1; } else if(nread == 0) break; //EOF nleft -= nread; ptr += nread; } return (n - nleft); }
writen函数:往一个描述字写n字节
ssize_t writen(int fd, const void *vptr, size_t n) { size_t nleft; size_t nwriten; const void *ptr; ptr = vptr; nleft = n while(nleft > 0){ if((nwriten = write(fd, ptr, nleft)) <= 0){ if(nwriten < 0 && errno == EINTR) //由于信号中断,没写成功任何数据 nwriten = 0; else return -1; } nleft -= nwriten; ptr += nwriten; } return (n); }
readline函数:从一个描述字读文本,一次1个字节
ssize_t readline(int fd, void *vptr, size_t maxlen) { ssize_t n, rc; char c, *ptr; ptr = vptr; for(n = 1; n < maxlen; ++n){ again: if((rc = read(fd, &c, 1)) == 1){ *ptr++ = c; if(c == ' ') //以'/n'结束 break; } else if(rc == 0){ *ptr = 0; return n -1; } else{ if(errno == EINTR) goto again; return -1; } } *ptr = 0; return n; }