是否有更清晰的方法可靠地使用write()函数?

Ank*_*rVj 6 c sockets linux gcc

我读的man页面,我的理解是,如果write()失败,并设置errnoEAGAIN或者EINTR,我可以执行write()了,所以我想出了下面的代码:

  ret = 0;
  while(ret != count) {
    write_count = write(connFD, (char *)buf + ret,  count);
    while (write_count < 0) {
      switch(errno) {
        case EINTR:
        case EAGAIN:
          write_count = write(connFD, (char *)buf + ret,  count -ret);
          break;
        default:
          printf("\n The value of ret is : %d\n", ret);
          printf("\n The error number is : %d\n", errno);      
          ASSERT(0);
      }
    }
    ret += write_count;
  }
Run Code Online (Sandbox Code Playgroud)

我正在表演read()write()插座,read()并按上述方式处理.我正在使用Linux,带gcc编译器.

Aln*_*tak 6

你有一点"不要重复自己"的问题 - 不需要两个单独的调用write,也不需要两个嵌套循环.

我的正常循环看起来像这样:

for (int n = 0; n < count; ) {
    int ret = write(fd, (char *)buf + n, count - n);
    if (ret < 0) {
         if (errno == EINTR || errno == EAGAIN) continue; // try again
         perror("write");
         break;
    } else {
        n += ret;
    }
}

// if (n < count) here some error occurred
Run Code Online (Sandbox Code Playgroud)

  • DRY(不要重复自己)是['实用程序员'](http://www.amazon.com/The-Pragmatic-Programmer-Journeyman-Master/dp/020161622X)一书中采用的原则.这意味着避免两次编写相同的代码.在这里,只要一次就足够,你就会写两次`write`语句. (3认同)
  • 在"EAGAIN/EWOULDBLOCK"的情况下,仅仅刻录CPU是不合适的.这种状态的分辨率取决于同行读取的东西.它不会自行消失.正确的过程是`select()`直到套接字变为可写. (3认同)