我有这个大多数原型的TCP套接字服务器接受连接,然后运行用户指定的程序与另一方交谈 . 神秘的事情是调用write()并返回,但没有输出到客户端 .

strace输出(作为执行程序运行“cat”)如下所示:

[pid  8142] read(0, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14"..., 32768) = 292
[pid  8142] write(1, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14"..., 292) = 292
[pid  8142] read(0, "", 32768)          = 0
[pid  8142] close(0)                    = 0
[pid  8142] close(1)                    = 0
[pid  8142] close(2)                    = 0

而在客户端,什么都没发生:

shell$ seq 100 | nc localhost 4445
shell$

我'd be ready to believe that the execve' d程序应该更像套接字处理套接字,就像使用send / recv / shutdown而不是read / write / close一样 - 但是我现在看到的文档似乎表明close()应该按设计工作并且只有半关闭连接才需要关闭 . The Unix Sockets FAQ提到未发送数据应该在关闭时刷新,而不设置任何SO_LINGER选项,并且Linux手册页套接字(7)声称“当套接字作为exit(2)的一部分关闭时,它总是在后台徘徊 . ”给它足够的输出会导致第一部分输出到客户端 .

为了完整起见,这是程序......

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <linux/net.h>
#include <netinet/in.h>

static int sock_fd_listen;
static struct sockaddr_in my_addr = {PF_INET, 0x5d11, 0x0100007f};
static struct 
static int one=1;
static int sockargs[]={0, 0, 0};

extern char **environ;

void step1()
{
  int retval;
  sock_fd_listen=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  retval=bind(sock_fd_listen, (struct sockaddr *)&my_addr,
          sizeof(struct sockaddr_in));
  if (retval==-1) {
    perror("bind");
    exit(1);
  }
  setsockopt(sock_fd_listen, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
  listen(sock_fd_listen, 5);
}


void main(int argc, char *argv[])
{
  static char buf[4096];
  int nconn=0;
  step1();
  while (1) {
    int conn_sock;
    pid_t pid;
    sockargs[0]=sock_fd_listen;
    conn_sock=accept(sock_fd_listen,NULL,NULL);
    pid=fork();
    if (pid==0) {
      dup2(conn_sock,0);
      dup2(conn_sock,1);
      close(conn_sock);
      execve(argv[1],argv+1,environ);
      fprintf(stderr, "execve failed: %s\n",strerror(errno));
      exit(-1);
    } else {
      close(conn_sock);
    }
  }
}