【问题标题】:TCP bus error in LinuxLinux 中的 TCP 总线错误
【发布时间】:2012-02-23 15:35:20
【问题描述】:

我有一个客户端-服务器应用程序,并且正在使用 tcp 套接字。根据来自客户端的 send() 请求,我总是收到总线错误并且程序终止。现在我做了一点维基百科搜索,文章将总线错误归因于(不存在的物理地址、未对齐的内存访问以及访问已被截断的 mmapped 文件)。我发送的结构只有三个整数和一个枚举实例,所以我认为对齐不是问题。下面是相关的sn-p代码:

typedef struct _commsg
{
    RequestType requestType;
    int client_pid;
    int request_id;
    int sector;
}ComMsg; 

在主目录中:

/* Create a reliable, stream socket using TCP */
if ((sock_id = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    DieWithError("socket() failed\n");

/* Construct the server address structure */
memset(&echoServAddr, 0, sizeof(echoServAddr));     /* Zero out structure */
echoServAddr.sin_family      = AF_INET;             /* Internet address family */
echoServAddr.sin_addr.s_addr = inet_addr(loopback_addr);   /* Server IP address */
echoServAddr.sin_port        = htons(SERVER_PORT); /* Server port */

/* Establish the connection to the echo server */
if (connect(sock_id, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
    DieWithError("connect() failed");


if (send(sock_id, (void *)&_commsg, sizeof(ComMsg), 0) != sizeof(ComMsg))
    DieWithError("send() sent a different number of bytes than expected");

在服务器端:

recv(clntSocket_fd, &_commsg, sizeof(ComMsg), 0);

提前致谢。

【问题讨论】:

  • 要么缺少重要的东西,要么你的编译器真的很奇怪!
  • 套接字 ID 是否有效? _commsg 到底是什么?请提供更多代码。
  • _commsg 是我在代码列表顶部指出的结构。我必须 &_commsg 因为 send 需要一个指向您尝试发送的数据的指针。顺便说一句,在执行此操作之前我还会检查 sock id,因此该过程正在创建一个有效的 socket_id。
  • @Aladdin:那甚至不应该编译..
  • 嗯,帖子被删除了,但我在 main 中有一个名为 ComMsg _commsg 的局部变量。这就是它编译的原因。对困惑感到抱歉。关于字节序,我在这个项目中使用了环回地址,所以发送结构应该没有问题。

标签: c linux sockets bus-error


【解决方案1】:

您是否在编译您的应用程序时打开了完整的警告(例如,使用 gcc、-Werror)?你应该。几乎可以肯定,总线错误意味着您正在访问错误的指针,在传递给函数的参数中违反了 API,等等。尝试在打开完整警告的情况下进行编译,干净地修复您看到的每个错误,看看是否能解决您的问题.

顺便说一句,对于 TCP 套接字,read(2) 和 write(2) 比 send(2) 和 recv(2) 更常用。

【讨论】:

    【解决方案2】:

    如 send(2) 手册页中所述“send() 之间的唯一区别 和 write(2) 是标志的存在。使用零标志参数, send() 等价于 write(2)"

    正如 Stevens 在他的 Unix Network Programming Book 中所述。 “溪流 套接字(例如 TCP 套接字)表现出读写行为 与普通文件 I/O 不同的功能。读或写 流套接字可能输入或输出的字节数少于请求的字节数"

    因此可能希望以这种方式测试错误:

      if (send(sock_id, (void *)&_commsg, sizeof(ComMsg), 0) < 0)
    

    并且不测试发送的字节。您可能正在关闭您的申请 当它实际上没有问题时。

    除了通过网络发送结构通常不是一个好的 想法,因为您在连接时可能会遇到与字节序相关的问题 对于与您不同的其他系统,首选方法是使用字节字符串。

    【讨论】:

      【解决方案3】:

      使用strace -esendgdb 运行您的客户端可能会受到启发。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-18
        • 2011-07-24
        • 1970-01-01
        相关资源
        最近更新 更多