为什么我在send()函数中丢失了这个字节?

时间:2010-02-12 17:03:49

标签: c sockets winsock

我们的应用程序是与Windows Java客户端通信的C服务器(此问题适用于所述服务器的Windows端口)。在这个特定的实例中,我们将数据发送到客户端,特别是,消息由一个7字节的头部组成,其中前3个字节都具有特定含义(操作类型,标志等),后4个字节包含大小其余的消息。出于某种原因,我绝对无法弄清楚,标题中的第三个字节是以某种方式改变的;如果我在send()上设置断点,我可以看到第三个字节是我期望的(0xfe),但是当我检查客户端时,该字节被设置为0。其他字节很好。 A使用WireShark进行了一些流量捕获,并看到该字节为0离开服务器,我发现更令人费解。第三个字节通过define,ala:

设置
#define GET_TOP_FRAME   0xfe

我做的一些测试进一步混淆了这个问题:

  1. 我将使用定义的值更改为第一个0x640xff0xfd:所有人都遇到了客户。
  2. 我将使用define的值更改为使用0xfe本身:客户端的值为零。
  3. 我将定义本身的值从0xfe更改为0xef:客户端的值为零。
  4. 没有任何关于这一点的舔。代码经历了几个级别的函数,但这里是大多数核心代码:

    int nbytes; /* network order bytes */
    static int sendsize = 7;
    unsigned char tbuffer[7];
    tbuffer[0]= protocolByte;
    tbuffer[1]= op;
    tbuffer[2]= GET_TOP_FRAME;
    nbytes = htonl(bytes);
    memcpy((tbuffer+3), &nbytes, JAVA_INT);
    
    send(fd, tbuffer, sendsize, 0);
    

    fd是先前放在一起的套接字,protocolByteopbytes是先前设置的。然后,它会在此消息之后立即发送一条非常类似的发送命令。正如我所提到的,如果我在该发送函数上设置了一个断点,那么tbuffer就包含了我期望的内容。

    有人有任何想法吗?我完全被难倒;这对我来说没有任何意义。感谢。

2 个答案:

答案 0 :(得分:1)

可能是你的系统中有一个简单的错误在做一个简单的缓冲区溢出或者类似的东西,但是鉴于这些信息很少,很难分辨出来。但是,请记住:

TCP不发送消息 - 它是一个流。一个send()调用可能需要几次recv()调用才能接收。一个recv调用可能会收到应用程序定义的部分“消息”。

你在检查发送的返回值吗?和recv的返回值? send可能会发送比您告诉它更少的字节。 recv可能会收到比你告诉它更少的字节,或者如果你给它一个足够大的缓冲区,它可能会收到比你的一个应用程序“消息”更多的数据。

答案 1 :(得分:0)

结果发现其他东西正在阻碍:除了C服务器之外,我们还有一个Tomcat / Java服务器,它运行在所有东西之上;老实说,我没有参与那个开发项目,所以我不太了解它。事实证明,我们有一些代码在该middletier部分和我们的客户之间共享;这个共享代码在离开服务器时占用了该特定字节,如果设置为0xfe,则将其设置为未初始化的值(因此为零)。然后,当它到达客户端时,它是错误的。这就是为什么当我将值设置为C代码中的不同内容时,它将其转移到另一方,以及为什么行为似乎不一致;我在Java中切换了很多值来看看发生了什么。

感谢所有指针,但事实证明这仅仅是我不能正确理解路径的情况。