Socket.ReceiveMessageFrom()的端点参数是什么?

时间:2010-03-01 23:02:52

标签: c# .net sockets

我正在编写一个iSCSI代理应用程序来做一些诊断工作(想想用于iSCSI的Fiddler) - 我试图一次捕获一个数据包,我不想读取任意大小并最终得到所有一个iSCSI数据包和另一半的数据包 - 我真的希望看到与Wireshark显示的相同类型的数据。在这样做时,我正在使用Socket.ReceiveMessageFrom()

然而,其中一个参数被称为“端点”,我不太清楚如何处理它。有线索吗?这是我的代码,你能告诉我,如果我完全偏离基础:

Tuple<byte[], int> readOnePacket(TcpClient conn) {
    var flags = SocketFlags.None;
    EndPoint endpoint = null;   /*** You can't set this to null!! ***/
    byte[] buffer = new byte[10 * 0x100000];
    int offset = 0;
    int bytes_received;

    do {
        IPPacketInformation packet_information;
        bytes_received = conn.Client.ReceiveMessageFrom(buffer, offset, BufferSize,
                                                        ref flags, ref endpoint, out packet_information);

        if (flags == SocketFlags.Partial) {
            // We only want to transfer full packets
            offset = bytes_received;
            continue;
        }                        
    } while (false);

    return new Tuple<byte[], int>(buffer, bytes_received + offset );
}

2 个答案:

答案 0 :(得分:1)

它不是TcpClient.ReceiveMessageFrom(),而是Socket.ReceiveMessageFrom()

如果你看一下documentation,你会看到以下内容:

  

通过引用传递的EndPoint   代表远程服务器。

修改: 将它设置为null确实是一个坏主意。

答案 1 :(得分:1)

虽然不能直接回答你的问题,但我认为这个答案仍然有用(尽管自提出问题以来已经过了很多时间)。

因为我不知道iSCSI是通过TCP还是通过普通IP工作,所以我无法为您的问题提供解决方案。但总的来说,TCP是一种面向流的协议,并没有“消息”的概念。另一方面,IP是面向数据报(即消息)的协议,它具有消息概念。在您的代码中,您尝试从TCP套接字读取“消息”(IP构造),这将无法正常工作。是的,TCP基于IP,但TCP数据报在TCP级别上不可见。

您提到的问题(阅读完整邮件,而不读入下一篇文章)仅适用于TCP级别,因为在IP上您确实可以阅读一条完整的邮件。如果您想在TCP级别上执行相同的操作,则需要使用具有消息支持的协议。通常要实现这一点,您需要拥有基于TCP的协议,并使用以下消息:

[msg header] [msg body]

其中[msg header]由以下内容组成:

[msg type] [msg body length]

Msg类型和msg体长具有固定长度(例如,msg类型为2个字节,体长为4个字节),并且msg体可以具有可变长度,因此您可以读取完整标头,然后确定正文的长度,并基于阅读全身。

希望这有帮助。