I am writing a proxy application for iSCSI to do some diagnostic work (think Fiddler for iSCSI) - I'm trying to capture data one packet at a time, I don't want to开发者_JS百科 read arbitrary sizes and end up getting all of one iSCSI packet and half of another - I really want to see the same kind of data as Wireshark would display for example. In doing this, I'm using Socket.ReceiveMessageFrom()
.
However, one of the parameters is called "endpoint", and I'm not quite sure what to do with it. Any clues? Here's my code, can you tell me if I'm completely off base:
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 );
}
It is not TcpClient.ReceiveMessageFrom(), but Socket.ReceiveMessageFrom()
If you take a look at the documentation, you will read the following:
An EndPoint, passed by reference, that represents the remote server.
Edit: Setting it to null is, indeed, a bad idea.
While not a direct answer to your question, I think this answer can still be useful (though lots of time passed since the question was asked).
Because I don't know if iSCSI works over TCP or over plain IP, I cannot offer a solution for your problem. But in general, TCP is a stream-oriented protocol, and doesn't have a notion of "message". On the other hand, IP is a datagram (i.e. message) oriented protocol, and it has notion of message. In your code, you're trying to read a "message" (IP construct) from TCP socket, and that will not work. Yes, TCP is based on IP, but IP datagrams are not visible on TCP level.
The problem you've mentioned (read full message, without reading into the next one) is applicable to TCP level only, because on IP you really can read one whole message. When you want the same thing on TCP level, you need to use a protocol with message support. Usually to achieve this you need to have you own protocol, based on TCP, with messages like this:
[msg header][msg body]
where [msg header] consists of something like:
[msg type][msg body length]
Msg type and msg body length have fixed length (say, 2 bytes for msg type and 4 bytes for body length), and msg body can have variable length, so you can read full header, then determine how long the body is, and based on that read full body.
Hope this helps.
精彩评论