views:

432

answers:

5

I'm trying to interact with an application over the network which uses a simple protocol. I have to send a header that looks like this:

2 bytes = Data Length (including Request Type)
1 byte = Request Type

I'm taking both parameters as integers:

private static void WriteHeader(Stream buf, int length, int requestType) {
    buf.Write(BitConverter.GetBytes(length), 0, 2);
    buf.WriteByte((byte)requestType);
}

I'm calling it like this:

byte[] outBuf = new byte[256];
using (MemoryStream outStream = new MemoryStream(outBuf)) {
    // Socket connection stuff here
    WriteHeader(outStream, 1, 110);
    sock.Send(outBuf);
    // Receive stuff here, never returns
}

I don't get any kind of exception when calling this method or sending outBuf over a socket, but the network application never responds. I can query it with other programs, though, so I'm fairly certain that it's because my header isn't being written correctly.

Am I doing something wrong when writing the values?

EDIT: Added MemoryStream code

+1  A: 

What type of stream is it? If its buffering your input, the data may never actually be sent across the wire.

Edit:

BitConverter.GetBytes(1) gives you [1, 0, 0, 0], from which you are passing [1,0]. Maybe its an endian-ness issue. Try sending [0,1] as your header.

Nader Shirazie
It's a MemoryStream pointed at a byte array.
David Brown
I think this is it. Specifying { 0, 1 } directly to WriteBytes made the receive call return. Now the only problem is that the server isn't sending any data. I don't think that's a problem with this code, though.
David Brown
A: 

I suspect you need to make your length a short. When you wrtie the int to the stream I suspect you're only going to get the top two bytes since the int is 4 bytes and you're only writing two of them to buf.

sipwiz
Unfortunately, changing it to short doesn't do anything. I wish it were that easy. :(
David Brown
+1  A: 

Could there be endian-ness issues between your client and the server? You could try capturing the network traffic with Wireshark or similar tool, then compare the packets sent/received using your client versus some other application that communicates successfully.

Jim Lewis
At the moment, I can only run the server application on my local PC. Wireshark can't capture packets on localhost. I have to send data to an IP address (127.0.0.1, in this case), which isn't supported with a loopback adapter, either.
David Brown
+1  A: 

Try a NetworkStream:

void WriteHeader(Stream s, int len, int cmd) {
    var buf = new byte[3];
    s.Write(BitConverter.GetBytes((UInt16)len));
    s.WriteByte((byte)cmd);
}

var ns = new NetworkStream(sock);
WriteHeader(ns, 1, 110);
joshperry
+1  A: 

I can think of three sources of errors in this code:

  • endianness problems: what is the byte order for the 2 bytes length that you send, and are you certain that GetBytes gives the bytes in the right order?
  • packet size: you are sending 256 bytes of data, even though your message is only 3 bytes in size.
  • payload: you don't put any payload in the message, but message 110 may require additional data.
Martin v. Löwis