Linux网络编程-readn函数、writen函数、readline函数实现
readn函数功能:在网络编程的读取数据中,通常会需要用到一个读指定字节才返回的函数,linux系统调用中没有给出,需要自己封装。
readn实现代码:
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; }
writen函数功能:读满n个字节才返回
writen代码实现:
1 int writen(int fd, const void *vptr, size_t n) 2 { 3 size_t nleft = n; //writen函数还需要写的字节数 4 ssize_t nwrite = 0; //write函数本次向fd写的字节数 5 const char* ptr = vptr; //指向缓冲区的指针 6 7 while (nleft > 0) 8 { 9 if ((nwrite = write(fd, ptr, nleft)) <= 0) 10 { 11 if (nwrite < 0 && EINTR == errno) 12 nwrite = 0; 13 else 14 return -1; 15 } 16 nleft -= nwrite; 17 ptr += nwrite; 18 } 19 return n; 20 }
readline函数功能:读到'\n'或者读满缓冲区才返回
readline函数实现:
1 static ssize_t readch(int fd, char *ptr) 2 { 3 static int count = 0; 4 static char* read_ptr = 0; 5 static char read_buf[1024*4] = {0}; 6 7 if (count <= 0) 8 { 9 again: 10 count = read(fd, read_buf, sizeof(read_buf)); 11 if (-1 == count) 12 if (EINTR == errno) 13 goto again; 14 else 15 return -1; 16 else if (0 == count) 17 return 0; 18 read_ptr = read_buf; 19 } 20 count--; 21 *ptr = *read_ptr++; 22 return 1; 23 } 24 25 ssize_t readline(int fd, void *vptr, size_t maxlen) 26 { 27 ssize_t i = 0; 28 ssize_t ret = 0; 29 char ch = '\0'; 30 char* ptr = NULL; 31 32 ptr = (char *)vptr; 33 34 for (i = 1; i < maxlen; ++i) 35 { 36 ret = readch(fd, &ch); 37 if (1 == ret) 38 { 39 *ptr++ = ch; 40 if ('\n' == ch) 41 break; 42 } 43 else if (0 == ret) 44 { 45 *ptr = 0; 46 return i-1; 47 } 48 else 49 return -1; 50 } 51 *ptr = 0; 52 return i; 53 }