[C#] Invisible TCP packets?

Started by
5 comments, last by hplus0603 11 years, 9 months ago
Wow, it's great to be back... last time I posted here was about 9 months ago I believe... smile.png
It looks like I need the help of the GDNet community once more. smile.png

So recently I started learning some basic network programming in games. I am currently creating a game where the same program can act as both a client and host a multiplayer session. I am only doing LAN communication atm using direct IP address input (the user has to enter the IP address of the host of the game in order to join).
I implemented basic TCP connection in .Net using the System.Net.Sockets.TcpListener/TcpClient classes, and managed to establish a connection between 2 computers in my house. However, when I try to write data to the NetworkStream returned by TcpClient.GetStream() method (specifically 44 bytes, if it makes a difference) I do not receive input on my other end.
I tried using the same computer as both the Host and the Client by launching two instances of my program, and using 3 different packet analyzers to try to track the packets, however I find that nothing shows, not even the handshake establishment... (is this because of loopback, perhaps?) I did not try to track packets between two different PCs.

Questions:

  1. Can I track packets on a loopback address? If yes, what program does it?
  2. Perhaps the amount of data I'm writiing is not large enough to send the packet? Can I overcome this and send exactly 44 bytes anyway?
  3. From the code below, am I even doing it right?

Object declarations:
[source lang="csharp"]me = new IPEndPoint(MyIpAddress, port);
tcpl = new TcpListener(me);
tcpl.ExclusiveAddressUse = false;
tcpc = new TcpClient();
tcpc.ExclusiveAddressUse = false;
players = new List<TcpClient>();[/source]
Connection Establishment:
[source lang="csharp"]// hosting is True if the user choses to host a game
if (hosting)
{
tcpl.Start(); // start listening on the port specified
while (!tcpl.Pending())
System.Threading.Thread.Sleep(2); // just waiting, will be replaced later with something better
while (tcpl.Pending())
players.Add(tcpl.AcceptTcpClient()); // accept a tcp connection request
tcpl.Stop(); // stop listening
}
else // the user wants to join a hosted game
{
tcpc.Connect(HostIpAddress, port); // ask for connection from host
}[/source]
Later, data send & receive:
[source lang="csharp"]if (hosting)
{
byte[] data = new byte[44];
// here data gets initialized...
foreach (TcpClient player in players)
player.GetStream().Write(data, 0, data.Length);
}
else // read data
{
NetworkStream stream = tcpc.GetStream();
byte[] data = new byte[44];
stream.Read(data, 0, 44);
// working with data here...
}[/source]
Advertisement

Wow, it's great to be back... last time I posted here was about 9 months ago I believe... smile.png
It looks like I need the help of the GDNet community once more. smile.png

So recently I started learning some basic network programming in games. I am currently creating a game where the same program can act as both a client and host a multiplayer session. I am only doing LAN communication atm using direct IP address input (the user has to enter the IP address of the host of the game in order to join).
I implemented basic TCP connection in .Net using the System.Net.Sockets.TcpListener/TcpClient classes, and managed to establish a connection between 2 computers in my house. However, when I try to write data to the NetworkStream returned by TcpClient.GetStream() method (specifically 44 bytes, if it makes a difference) I do not receive input on my other end.
I tried using the same computer as both the Host and the Client by launching two instances of my program, and using 3 different packet analyzers to try to track the packets, however I find that nothing shows, not even the handshake establishment... (is this because of loopback, perhaps?) I did not try to track packets between two different PCs.

Questions:

  1. Can I track packets on a loopback address? If yes, what program does it?

  2. Perhaps the amount of data I'm writiing is not large enough to send the packet? Can I overcome this and send exactly 44 bytes anyway?

  3. From the code below, am I even doing it right?

Object declarations:
[source lang="csharp"]me = new IPEndPoint(MyIpAddress, port);
tcpl = new TcpListener(me);
tcpl.ExclusiveAddressUse = false;
tcpc = new TcpClient();
tcpc.ExclusiveAddressUse = false;
players = new List<TcpClient>();[/source]
Connection Establishment:
[source lang="csharp"]// hosting is True if the user choses to host a game
if (hosting)
{
tcpl.Start(); // start listening on the port specified
while (!tcpl.Pending())
System.Threading.Thread.Sleep(2); // just waiting, will be replaced later with something better
while (tcpl.Pending())
players.Add(tcpl.AcceptTcpClient()); // accept a tcp connection request
tcpl.Stop(); // stop listening
}
else // the user wants to join a hosted game
{
tcpc.Connect(HostIpAddress, port); // ask for connection from host
}[/source]
Later, data send & receive:
[source lang="csharp"]if (hosting)
{
byte[] data = new byte[44];
// here data gets initialized...
foreach (TcpClient player in players)
player.GetStream().Write(data, 0, data.Length);
}
else // read data
{
NetworkStream stream = tcpc.GetStream();
byte[] data = new byte[44];
stream.Read(data, 0, 44);
// working with data here...
}[/source]

For the answer to 3. Packets should indeed send automatically after some time, although to get it sending just about instantaneously change the TcpClient.NoDelay boolean to true. Tcp packets have large headers on them though so doing this can increase bandwidth consumption. When TcpClient.NoDelay is set to false (which is the default) it waits some time collect more data and send possibly several messages in one packet.
Also instead of using .GetStream for every player just create a object of NetworkStream and use that (i.e. create a list of a class that has both TcpClient and NetworkStream members in it).

change the TcpClient.NoDelay boolean to true

I will try that now, thanks for replying.
Never mind the OP, I found my problem. I was accidentally ignoring the 4th byte of my data, causing everything to shift by one - causing my program to freeze. Stupid me wacko.png
Just for the record, it isn't always easy to capture loopback traffic, especially on Windows, because of how it works. I believe there are some specialty drivers which make this available, though. A little bit of time on Google should turn up some tricks for capturing loopback traffic :-)

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Yes, Windows loopback is very difficult to capture. Linux loopback is much easier -- "tcpdump -i any" does the trick.
On Windows, you can try:
- Try using the IP of the machine (192.168.1.2 or whatever ipconfig says) instead of localhost/127.0.0.1
- Try setting up port forwarding on your router, and connect to that (if the router supports hairpin NAT)
- Build a simple TCP tunneling/proxying program, and use that to capture data
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement