写入socket后程序自动关闭

时间:2014-09-11 21:53:10

标签: c file sockets io stream

我有以下代码:

  bytes_read = read(0, buffer_stdin, 65535);
  printf("bytes read from stdin: %d\n", bytes_read);
  bytes_written = write(sock, buffer_stdin, bytes_read);
  printf("bytes written to socket: %d\n", bytes_written); 

sock是套接字描述符。在代码中,我已将套接字连接到服务器并返回连接(0),表明连接成功。

现在在上面的代码中我输入了一些东西到stdin,让我们说“你好”,读取的字节数是6(因为字母“o”后的空终止)。程序执行第一个print语句。

但由于某种原因,程序不执行第二个print语句。它只是退出。

当我在第3行注释掉我写入套接字的地方时,第二个print语句就会执行。

我的问题是,为什么程序会在没有我指示的情况下提前退出?

这是初步代码:

int main(int argc, char *argv[]) {
  if (argc != 3) {
    printf("Invalid arguments\n");
    exit(1);
  }

  char *serverIP = argv[1]; /*Server hostname*/
  char *portNumber = argv[2]; /*Port Number*/
  void *numericAddress;
  char buffer_stdin[65535];
  char buffer_stdout[65535];
  int bytes_read = 0;
  int bytes_written = 0;

  /*getting integral number of string representation of port number*/
  in_port_t servPort = atoi(argv[2]);

  /*------------------get binary number of hostname-----------------*/
  struct addrinfo addrCriteria;
  memset(&addrCriteria, 0, sizeof(addrCriteria));
  addrCriteria.ai_family = AF_INET;
  addrCriteria.ai_socktype = SOCK_STREAM;
  addrCriteria.ai_protocol = IPPROTO_TCP;

  struct addrinfo *addrList;

  int rtnVal = getaddrinfo(serverIP, portNumber, &addrCriteria, &addrList);
  if (rtnVal != 0) {
    printf("getaddrinfo() failed\n");
    exit(1);
  }
  if (rtnVal == 0) {
    printf("getaddrinfo() successful\n");
  }

  numericAddress = &((struct sockaddr_in *) (addrList->ai_addr))->sin_addr;
  ((struct sockaddr_in *)(addrList->ai_addr))->sin_port = htons(servPort);
  /*----------------------------------------------------------------*/

  /*Creating socket*/
  int sock = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
  if (sock < 0) {
    printf("error creating socket\n");
    exit(1);
  }

  /*Establish connection to the echo server*/
  int r = connect(sock, (struct sockaddr *) addrList, sizeof(addrList));
  if (r < 0) {
    printf("Connection failed\n");
    exit(1);
  }
  if (r == 0) {
    printf("connection succesful\n");
  }

1 个答案:

答案 0 :(得分:2)

SIGPIPE

问题似乎是服务器在客户端有机会发送数据之前关闭了连接。写入闭合的套接字可能会导致一种错误,表示为提升SIGPIPE信号,除非该信号被忽略。如果SIGPIPE的信号传递被抑制(通过将其处置设置为SIG_IGN),写入关闭的套接字将导致错误结果,errno设置为EPIPE。

由于您的程序不会忽略SIGPIPE或以其他方式处理它,因此使用默认处理程序,这可能会导致程序终止。这解释了您当前的问题。

特权端口80

您在评论中表示您使用了端口80作为&#34; echo服务器&#34;。除非您以root身份运行程序,否则80在特权端口范围内,因此您的程序将无法侦听该端口。此外,端口80是HTTP服务的众所周知的端口。所以,即使你启动了&#34; echo服务器&#34;使用root权限时,它仍然可能会失败,因为某些其他服务器(Web服务器)已经在该端口上侦听。

假设您将客户端定向到Web服务器,则不知道客户端尝试通信时实际发生了什么。例如,Web服务器可能在客户端连接后立即传送了RST数据包。连接成功完成,但写入失败。

要获得您期望的行为,您应该为您的&#34; echo服务器&#34;选择一个非特权端口。相对较高且随机的东西,因此它不会与其他程序冲突,并且如果您在共享计算机上,则不会与其他用户冲突。