我正在编写一个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 );
}
答案 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体可以具有可变长度,因此您可以读取完整标头,然后确定正文的长度,并基于阅读全身。
希望这有帮助。