select() 后关闭套接字

Posted

技术标签:

【中文标题】select() 后关闭套接字【英文标题】:Close socket after select() 【发布时间】:2013-04-23 13:50:40 【问题描述】:

我正在编写一个 IRC 客户端,我想实现一个“/server”命令来将我的客户端的连接切换到另一个服务器。 在初始化新连接之前,我想关闭 sockect 的 fd 但 close() 调用失败。谁能告诉我为什么? 这是我的代码:

/* Main execution loop */
FD_ZERO(&irc->rdfs);
FD_SET(STDIN_FILENO, &irc->rdfs);
FD_SET(irc->socket_fd, &irc->rdfs);
if ((select(irc->socket_fd + 1, &irc->rdfs, NULL, NULL, NULL)) == -1)

  if ((close(irc->socket_fd)) == -1)
    exit(usage(CLOSE_ERROR));
  exit(usage(SELECT_ERROR));

if (FD_ISSET(STDIN_FILENO, &irc->rdfs))

  fgets(irc->buffer, SIZE - 1, stdin);
  
    p = strstr(irc->buffer, RET);
    if (p != NULL)
      *p = 0;
    else
      irc->buffer[SIZE - 1] = 0;
  
  write_on_server(irc, irc->buffer); /* The function where I call switch_server() in */

else if (FD_ISSET(irc->socket_fd, &irc->rdfs))

  if ((read_on_server(irc)) == 0)
    exit(usage(SERVER_DISCONNECT));
  puts(irc->buffer);

这是我试图关闭套接字的 fd 的地方:

void            switch_server(t_irc *irc)

if ((close(irc->socket_fd)) == -1) /* This is the close which fail */
    exit(EXIT_FAILURE);


void            write_on_server(t_irc *irc, const char * buffer)

if (!(strncmp("/server", buffer, strlen("/server"))))
  switch_server(irc);
else
  if ((send(irc->socket_fd, buffer, strlen(buffer), 0)) < 0)
   
     if ((close(irc->socket_fd)) == -1)
       exit(usage(CLOSE_ERROR));
     exit(usage(CLIENT_SEND_ERROR));
   

非常感谢。

【问题讨论】:

【参考方案1】:

如果您想知道像 close() 这样的系统调用为何失败,请使用 perror() 将错误消息打印到 stderr,或使用 strerror(errno) 将错误代码转换为字符串并以其他方式输出。

【讨论】:

【参考方案2】:

几乎可以肯定套接字 FD 是无效的。你需要调用 perror() , and 在 select() 失败。

【讨论】:

以上是关于select() 后关闭套接字的主要内容,如果未能解决你的问题,请参考以下文章

套接字在 32739 次连接后不会关闭

发送后如何正确关闭套接字(使用 IOCP)?

检测非阻塞套接字上的关闭连接

在读取端收到关闭后需要帮助写入套接字

vb2010 (vb.net )Socket套接字当网络中断时或服务器意外关机,客户端如何自动重新连接服务端

关闭后从套接字读取数据