Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

How can I set the source port when connecting?

Discussion in 'Multiplayer' started by wm24, Jul 12, 2015.

  1. wm24

    wm24

    Joined:
    Jul 12, 2015
    Posts:
    2
    I'm trying to implement NAT punch through for port-restricted NAT's. I can do the punch though okay, but the problem is how to tell UNET the source port to use when connecting to the server. For instance, if I connect to a server on port 7777 and inspect the client process I see that it has randomly picked a source port (53692 in this case).

    What I'd like to do is to be able to do NAT punch through on a port I pick (say, 51000), then tell UNET "connect to server x on destination port 7777 with source port 51000." (The socket equivalent of this is binding a socket to a local endpoint with a specified port). But even the low level API in UNET doesn't seem to expose this (I've gone over the documentation several times but maybe I've missed it?).

    Does anyone have any idea how to do this? Or even if I could get the source port UNET is using after the fact?
     
    thegreatzebadiah likes this.
  2. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    574
    NetworkTransport.AddHost() function has port as parameter, in your case:
    int clientId = AddHost( ..., 51000, ..);
    Connect( clientId, ..., 7777);
     
  3. wm24

    wm24

    Joined:
    Jul 12, 2015
    Posts:
    2
    Thank you. I did figure this out eventually, however it didn't help me because what I really want is to use the high-level API (NetworkManager, NetworkClient, NetworkConnection, etc.). Even though the connectionId and hostId values can be changed via the NetworkConnection object, calling NetworkClient.Connect( ... ) will always internally create and use a new Host/socket with port=0.
     
  4. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    I know this is an old post but I'm trying to do the exact same thing now and running into the same problem. I'm so close to having the punchthrough working, I just can't figure out how to hook into the HLAPI. I'm on 5.4.0b3 is there any way I can set the port that NetworkClient connects from?
     
  5. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    Holy Crap I think I actually figured this out. It's a nasty little trick but it seems to be working. Instead of trying to set the port that the client uses to connect (which seems to be impossible) I tried setting the transport level host id instead. So first:

    Code (CSharp):
    1. socketID = NetworkTransport.AddHost(topo, portToConnectFrom);
    to create our own host on the desired port

    and then right after calling NetworkClient.Connect

    Code (CSharp):
    1. clientIDField = typeof(NetworkClient).GetField("m_ClientId", BindingFlags.NonPublic | BindingFlags.Instance);
    2. clientIDField.SetValue(client, socketID);
    For anyone unfamiliar, I'm using reflection to set the private field m_ClientId on the NetworkClient. It seems this has to be done after calling Connect since that is where unity sets it internally. It's likely that there will now actually be two transport level hosts, but it doesn't really matter. When the connection succeeds and the NetworkClient initializes its NetworkConnection object it does so with the proper hostId and connectionId so it seems like everything is set up right.

    I've actually got this working right now with the NAT Punchthrough from RakNet. I'm able to connect from outside my network with no port forwarding necessary. I wasn't able to connect without punchthrough or even with punchthrough until I implemented this fix to be able to set the port the client connected from. So I'm like 99% positive this works and the client is actually connecting from the correct port.
     
    Last edited: Mar 14, 2016
  6. UGTools

    UGTools

    Joined:
    Oct 10, 2012
    Posts:
    738
    Can you use NetworkClient.hostPort instead?
     
  7. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    As of 2017.1, yes, thankfully.