如何使用udp从c#客户端与c服务器通信?

时间:2011-08-02 17:30:20

标签: c# c sockets udp client-server

我的问题描述如下:

我的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);

... `` 我确信我在这整个过程中缺少一个基本方面。请帮我看看它是什么。任何帮助将不胜感激。

谢谢。

1 个答案:

答案 0 :(得分:2)

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

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

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