1

我正在使用 C 语言在 Linux 中使用命令通过套接字发送数据

send(ServerSocket, cSendBuff, strlen(cSendBuff), 0);

程序是:

  1. 创建套接字
  2. 连接到服务器
  3. while(条件):发送数据

当我在Linux环境下运行这个程序时,如果是连接的,就没有问题。但是为了在运行时处理失败的连接,我检查了一些情况并得到了如下结果:

情况1:

  1. 创建套接字:没有创建(注释掉创建函数)
  2. 连接到服务器:无连接(注释掉连接功能)
  3. 发送数据 -->失败(返回 -1)但没有崩溃

案例二:

  1. 创建套接字:成功
  2. 连接服务器:失败甚至无连接(注释掉连接功能)
  3. 发送数据 -->崩溃

然后,我尝试了 3 种不同的套接字值,但没有连接到服务器

案例3:

  1. ServerSocket = -1 --> 发送数据:失败
  2. ServerSocket = 0 --> 发送数据:失败
  3. ServerSocket = 4 --> 发送数据:崩溃

如果发送失败,这是正确的,但我不明白为什么在其他情况下我会崩溃。我尝试使用 Windows 但没问题,Linux 和 Windows 之间有什么不同吗?是否有意义?我只想打开套接字并连接到服务器一次,然后发送数据一千次,所以如果在这种情况下“崩溃”是有意义的,如果连接失败,我该如何解决这个问题?谢谢你的时间。

这是案例 2(通过停止服务器以测试连接失败的情况,连接失败):

ServerSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_IP) ;
...
iResult = connect(ServerSocket,(struct sockaddrx *)&server , sizeof(server));
iResult = send(ServerSocket, cSendBuff, strlen(cSendBuff), 0);
if(iResult<0)
{...}

这是案例3:

    //ServerSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_IP) ;
    ...
    //iResult = connect(ServerSocket,(struct sockaddrx *)&server , sizeof(server));
    ServerSocket = 0;
    iResult = send(ServerSocket, cSendBuff, strlen(cSendBuff), 0);
    log();
    ServerSocket = -1;
    iResult = send(ServerSocket, cSendBuff, strlen(cSendBuff), 0);
    log();
    ServerSocket = 4;
    iResult = send(ServerSocket, cSendBuff, strlen(cSendBuff), 0);
    log();
    if(iResult<0)
    {...}
4

2 回答 2

14

您的程序不会 崩溃

它收到一个SIGPIPE信号,因为套接字的本地端已关闭。阅读man 2 send,尤其是EPIPE错误情况。(因此,准确地说,您的程序由于未处理的SIGPIPE信号而终止。)

正如man 7 signal手册页所说,默认处置SIGPIPE是终止进程。为避免终止,请设置SIGPIPE信号处理程序,或使用send(socket, buffer, length, MSG_NOSIGNAL).

不要将 Windows 用作量尺。这不是一个理智的方法。你有更好的,实际上可靠的文档可用。Linux 手册页项目是 C 库文档(第 3 节)的最佳来源之一。尽管它专注于 Linux 和 GNU C 库,但每个页面都有一个符合 部分,它告诉您该功能何时何地可用。

以上链接指的是最新的网页,但您也可以在命令行上使用man 2 send,来浏览相同的信息。man 7 signal网页比发行版更新,但该项目仅包括标准手册页,而不是那些由应用程序安装的手册页或您可能拥有的额外库。

问题?

于 2013-10-04T04:17:56.517 回答
0

案例 2.3:这应该失败,我的意思是它应该返回 -1 并附带一个值errno.You don't state you mean what you mean by 'fail' or 'crash',所以不可能进一步评论。

情况 3:除非 FD 0 或 4 恰好是一个套接字,否则这些都应该失败。

我不知道你为什么要测试这些。“连接失败”与从未连接过的套接字完全不同。“失败的连接”表现为来自send(), recv(),和朋友的 -1 返回,伴随的值errno不是EAGAIN/EWOULDBLOCK.你不能发送到未连接的 TCP 套接字,你的代码甚至不可能尝试一下。如果是,则您的错误处理代码路径不正确。

于 2013-10-04T03:49:40.017 回答