effy
effy

Reputation: 430

C# TCP Listen and Connect on the same Local Port

I have a C# Console Application where I'm trying to implement TCP Hole Punching.

I need to listen on a Local Port and at the same time (simultaneously/asynchronously) connect to 2 different remote hosts (in reality a remote hosts public and private endpoints) using the same Local Port.

As I understand I somehow need to bind the Sockets/Ports but I can't figure this out in C#.

There's the TCPListener, TCPClient and Socket classes and I don't know which ones to use to accomplish what I need.

I'm following this guide http://www.bford.info/pub/net/p2pnat/index.html Chapter 4.2

  1. From the same local TCP ports that A and B (Clients) used to register with (Server) S, A and B each asynchronously make outgoing connection attempts to the other's public and private endpoints as reported by S, while simultaneously listening for incoming connections on their respective local TCP ports.

I've already implemented the server part using NodeJS and it's working fine, I'm struggling with the Local Port stuff mentioned above.

Upvotes: 2

Views: 2377

Answers (2)

Calmarius
Calmarius

Reputation: 19441

You need to create two or more sockets, set SocketOptionName.ReuseAddress option on them, then bind all of them onto the same ip:port pair. Then listen with one of the sockets, and connect to the server or other peers with the others, this makes your public ip:port pair (possibly different than local because you are behind NAT) visible. So other peers can initiate connections to that, which result in incoming connections on the other listening socket.

In order to make this work your NAT needs to be compliant with the practices described in RFC5382.

Upvotes: 0

Robert Perry
Robert Perry

Reputation: 1954

I'm pretty sure that TCP only allows a 1-2-1 connection between client and server and ports. The only way to setup the multiple connections is to create two different sockets.

The TCP hole punching you're referring too I have tried before. You need to basically use the relay server to tell both A and B how to connect.. So do as follows:

1) Client A connects to Server on one port

2) Server tells Client B your IP and the port (this will be a new connection you will be setting up, different to your connection to the server)

3) Server tells Client A the IP and Port that Client B will be using

4) Client A uses the info provided to create a new connection directly to client B

5) Client B uses its info about your "new" connection to try and accept the incoming request

6) It might fail to handshake a couple of times due to latency, so build in some sort of repeater to keep trying the connection

7) You eventually should have a direct connection to B

Upvotes: 0

Related Questions