www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Extra packet sent when using socket/socketstream

reply Vidar Wahlberg <canidae exent.net> writes:
Here's a small program that doesn't do anything useful:
---
import core.thread;
import std.socket;
import std.socketstream;
import std.stdio;

void main() {
         auto socket = new TcpSocket(new 
InternetAddress("nethack.alt.org", 23));
         auto stream = new SocketStream(socket);
         stream.write(cast(char[])[0xff, 0xfb, 0x18, 0xff, 0xfa, 0x18, 
0x00, 'x', 't', 'e', 'r', 'm', 0xff, 0xf0, 0xff, 0xfc, 0x20, 0xff, 0xfc, 
0x23, 0xff, 0xfc, 0x27, 0xff, 0xfe, 0x03, 0xff, 0xfb, 0x01, 0xff, 0xfd, 
0x05, 0xff, 0xfb, 0x21, 0xff, 0xfb, 0x1f, 0xff, 0xfa, 0x1f, 0x00, 0x50, 
0x00, 0x18, 0xff, 0xf0]);
         //stream.flush();
         Thread.sleep(dur!("seconds")(1));
         char[4096] data;
         auto count = stream.readBlock(&data, data.length);
         writefln("%s - %s", count, data[0 .. count]);
         stream.write(cast(char[])"l");
         //stream.flush();
         Thread.sleep(dur!("seconds")(1));
         count = stream.readBlock(&data, data.length);
         writefln("%s - %s", count, data[0 .. count]);
}
---

I'm seeing some peculiar results when executing this program. That is, I 
captured the data transmitted to nethack.alt.org using Wireshark and saw 
the following data being sent:
Telnet packet 1 (timestamp: 1.526691):
0000   2f 00 00 00 00 00 00 00

Telnet packet 2 (timestamp: 1.702938):
0000   ff fb 18 ff fa 18 00 78 74 65 72 6d ff f0 ff fc
0010   20 ff fc 23 ff fc 27 ff fe 03 ff fb 01 ff fd 05
0020   ff fb 21 ff fb 1f ff fa 1f 00 50 00 18 ff f0

Telnet packet 3 (timestamp: 2.528467):
0000   01 00 00 00 00 00 00 00


The second packet is identical to the data in my first call to 
"stream.write()", but why did it send "2f 00 00 00 00 00 00 00" (2f hex 
== 47 dec, which is the length of the first char-array I sent to 
"stream.write()") first?
It does the same thing for "l", which causes the server to hang up the 
connection before it even gets to send that "l".

I've tried the same thing in C++ (using sys/socket), that does not send 
a packet first telling how large the following packet will be, neither 
does simply "telnet nethack.alt.org".
I've also tried a number of ways to set up the socket:
new Socket(AddressFamily.INET, SocketType.[STREAM,RAW,SEQPACKET], 
ProtocolType.[TCP,IP,RAW]);

SocketType.SEQPACKET is apparently not supported on my system, and 
ProtocolType.RAW gives compilation error "Error: no property 'RAW' for 
type 'int'".


How can I make it not send a packet warning the recipient that it's 
about to receive another packet (of a given size)?
Feb 06 2012
parent reply "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Monday, 6 February 2012 at 21:51:54 UTC, Vidar Wahlberg wrote:
 How can I make it not send a packet warning the recipient that 
 it's about to receive another packet (of a given size)?

Don't use std.socketstream. Streams serialize some types in an internal format (in your case, prepending the length of arrays). If you only need to operate on raw bytes, it's simple to use std.socket directly.
Feb 07 2012
parent Vidar Wahlberg <canidae exent.net> writes:
On 2012-02-07 14:44, Vladimir Panteleev wrote:
 On Monday, 6 February 2012 at 21:51:54 UTC, Vidar Wahlberg wrote:
 How can I make it not send a packet warning the recipient that it's
 about to receive another packet (of a given size)?

Don't use std.socketstream. Streams serialize some types in an internal format (in your case, prepending the length of arrays). If you only need to operate on raw bytes, it's simple to use std.socket directly.

Thanks, that did the trick.
Feb 07 2012