【问题标题】:how to communicate with c server from c# client using udp?如何使用 udp 从 c# 客户端与 c 服务器通信?
【发布时间】:2011-08-02 17:30:19
【问题描述】:

我的问题描述如下:

我的C# 客户端使用sendto 发送一个udp 数据包。因为这是C#,所以这是我构造的字节数组。

C 服务器使用recvfrom 接收数据包。通过wireshark,我确认C#程序正在发送数据包,C程序正在接收它。 recvfrom 没有抛出任何错误。但我无法从收到的数据包中提取任何数据。我在一个 char 数组中接收它。

具体细节: 我发送的UDP 数据包是一个请求。 c 程序和C# 程序都知道请求的结构。但是由于我通过网络发送一个字节数组,所以这个结构是无关紧要的(我认为)。

代码: C#: 构建数据包: ``

            byte[] tmpB;
            int j = 0;
            char[] reqStr = rsField.reqStr;

            for (; j < reqStr.Length; j++)
            {                    
                tmpB = BitConverter.GetBytes((char)reqStr[j]);
                for (int ctr = 0; ctr < tmpB.Length; ctr++)
                    retVal[i++] = tmpB[ctr];

            }//end of for

            tmpB = BitConverter.GetBytes((UInt32)rsField.fieldLength);
            for (int ctr = 0; ctr < tmpB.Length; ctr++)
                retVal[i++] = tmpB[ctr];

            tmpB = BitConverter.GetBytes((UInt32)rsField.fieldType);
            for (int ctr = 0; ctr < tmpB.Length; ctr++)
                retVal[i++] = tmpB[ctr];

            //------------------------------------------------------------


            tmpB = BitConverter.GetBytes((UInt32)ctField.camType);
            for (int ctr = 0; ctr < tmpB.Length; ctr++)
                retVal[i++] = tmpB[ctr];

            tmpB = BitConverter.GetBytes((UInt32)ctField.fieldLength);
            for (int ctr = 0; ctr < tmpB.Length; ctr++)
                retVal[i++] = tmpB[ctr];

            tmpB = BitConverter.GetBytes((UInt32)ctField.fieldType);
            for (int ctr = 0; ctr < tmpB.Length; ctr++)
                retVal[i++] = tmpB[ctr];

... `` 如您所见,我混合了字符串和数字字段。 (这些不是我唯一拥有的字段,为了便于阅读,代码被缩写)

C: ``

            char buf[1000];
    memset(&buf,'\0',sizeof(buf));
    length = recvfrom (i, &buf, sizeof(buf), 0,
               (struct sockaddr *)&remoteAddr, &fromLen);


    now = time(0);
    if (length == -1) {
        fprintf (stderr, "%s: recvfrom error - %m\n", ctime(&now));
        continue;
    }
    unsigned long fieldType1 = strtoul(bufPtr,0,10);
    bufPtr += 4 * sizeof(char);
    unsigned long fieldLength1 = strtoul(bufPtr,0,10);
    bufPtr += 4 * sizeof(char);
    unsigned long res = strtoul(bufPtr,0,10);

    printf("fieldType: %ld \t fieldLength: %ld \t res: %ld \t \n",fieldType1,fieldLength1,res);

... `` 我确信我错过了整个事情的一个基本方面。请帮我看看它是什么。任何帮助将不胜感激。

谢谢。

【问题讨论】:

    标签: c# c sockets udp client-server


    【解决方案1】:

    一旦位被写入线路,它就不是 C、C++、C#、Java、FORTRAN、COBOL、lisp、scheme、scala 或其他任何东西。是电线上的一点点。这是您缺少的基本方面。网络上的数据没有结构。

    一旦您读取数据,您就可以获取这个字节集合并对其应用结构。这意味着您需要知道前四个字节代表一个数字,并且低位字节存储在有效负载开头的偏移量 0 处,下一个高位字节位于偏移量 1 处,下一个高位字节位于偏移量处2,最高位字节在偏移量3。您的具体示例可能与上面的描述没有共同之处,但是如何打包成字节和解包出字节的想法是您需要特别注意的。

    在最低级别验证您正在写入所有字节。保留哪些数据在哪些字节中的映射,然后独立于您刚刚编写的规范编写通信的每一端。不要试图将整个整数/短裤/数据结构写入数据包而不将它们转换为字节;否则,你会发现两端的机器可能对整数/短/数据结构的表示方式有不同的看法。

    【讨论】:

    • 嗨,你说的很有道理。但是我已经验证了我要发送的内容正在被发送,并且它正在被发送时被完全接收。这是因为我逐字节写入缓冲区。不过,我最初的问题仍然存在。我如何在服务器端接收它?在 char 数组中接收它有什么问题吗?如前所述,wireshark 确认数据包发送正确。
    • 在服务器端,你应该接受一个字节数组。根据语言的不同,char 数组可能是相同的东西(就像在 C 中一样),但在其他语言中,char 是多字节的。如果您在多字节字符环境中接收,您会发现这些字节是在没有您明确控制的情况下打包的(因此可能会出错)。确保将有效负载视为字节数组,然后显式写入从字节到其他项的映射。
    猜你喜欢
    • 2021-12-20
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多