I wrote up some code to help me understand Unity’s Transport Layer API. I created a “client” script and a “server” script. I then attached these two scripts to a Main Camera and hit Play. If you want, you can attach more than one “client” script.
When the client connects, I can choose how big of a message to send. When the server receives a message, it then echoes it back to everyone who’s connected.
When you call AddHost, I think it’s spawning a thread that then listens to and sends on the port.
Here is my “ClientUI.cs”:
using UnityEngine; using UnityEngine.Networking; public class ClientUI : MonoBehaviour { public void Start() { NetworkTransport.Init(); ConnectionConfig config = new ConnectionConfig(); reliableChannel = config.AddChannel(QosType.Reliable); HostTopology topology = new HostTopology(config, 1); // Only connect once // Do not put port since we are a client and want to take any port available to us #if UNITY_EDITOR m_hostId = NetworkTransport.AddHostWithSimulator(topology, 200, 400); #else m_hostId = NetworkTransport.AddHost(topology); #endif } Rect windowRect = new Rect(500, 20, 100, 50); string ipField = System.Net.IPAddress.Loopback.ToString(); string portField = "25000"; byte reliableChannel; int m_hostId = -1; int m_connectionId; Vector2 scrollPos; string sizeField = "1000"; string receiveLabel; public void OnGUI() { windowRect = GUILayout.Window(GetInstanceID(), windowRect, MyWindow, "Client Window"); } void MyWindow(int id) { GUILayout.BeginHorizontal(); GUILayout.Label("IP"); ipField = GUILayout.TextField(ipField); GUILayout.Label("Port"); portField = GUILayout.TextField(portField); if (GUILayout.Button("Connect")) { byte error; int connectionId; connectionId = NetworkTransport.Connect(m_hostId, ipField, int.Parse(portField), 0, out error); if (connectionId != 0) // Could go over total connect count m_connectionId = connectionId; } if (GUILayout.Button("Disconnect")) { byte error; bool ret = NetworkTransport.Disconnect(m_hostId, m_connectionId, out error); print("Disconnect " + ret + " error " + error); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Size"); sizeField = GUILayout.TextField(sizeField); if (GUILayout.Button("Send")) { byte error; byte[] buffer = new byte[int.Parse(sizeField)]; // Just send junk bool ret = NetworkTransport.Send(m_hostId, m_connectionId, reliableChannel, buffer, buffer.Length, out error); print("Send " + ret + " error " + error); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); scrollPos = GUILayout.BeginScrollView(scrollPos, GUILayout.Height(200.0f), GUILayout.Width(400.0f)); GUILayout.Label(receiveLabel); GUILayout.EndScrollView(); GUILayout.BeginHorizontal(); if (GUILayout.Button("Clear")) { receiveLabel = ""; } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUI.DragWindow(); } public void Update() { if (m_hostId == -1) return; int connectionId; int channelId; byte[] buffer = new byte[1500]; int receivedSize; byte error; NetworkEventType networkEvent = NetworkTransport.ReceiveFromHost(m_hostId, out connectionId, out channelId, buffer, 1500, out receivedSize, out error); if (networkEvent == NetworkEventType.Nothing) return; receiveLabel += string.Format("{0} connectionId {1} channelId {2} receivedSize {3}\n", networkEvent.ToString(), connectionId, channelId, receivedSize); } }
My “ServerUI.cs”:
using UnityEngine; using UnityEngine.Networking; using System.Collections.Generic; using System.Net; public class ServerUI : MonoBehaviour { public void Start() { NetworkTransport.Init(); ConnectionConfig config = new ConnectionConfig(); reliableChannel = config.AddChannel(QosType.Reliable); HostTopology topology = new HostTopology(config, 5); // Allow five connections #if UNITY_EDITOR m_hostId = NetworkTransport.AddHostWithSimulator(topology, 200, 400, 25000); #else m_hostId = NetworkTransport.AddHost(topology, 25000); #endif } Rect windowRect = new Rect(20, 20, 100, 50); Dictionary<int, IPEndPoint> connectionDictionary = new Dictionary<int, IPEndPoint>(); byte reliableChannel; int m_hostId = -1; Vector2 scrollPos; string receiveLabel; public void OnGUI() { windowRect = GUILayout.Window(GetInstanceID(), windowRect, MyWindow, "Server Window"); } void MyWindow(int id) { scrollPos = GUILayout.BeginScrollView(scrollPos, GUILayout.Height(200.0f), GUILayout.Width(400.0f)); GUILayout.Label(receiveLabel); GUILayout.EndScrollView(); GUILayout.BeginHorizontal(); if (GUILayout.Button("Clear")) { receiveLabel = ""; } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUI.DragWindow(); } public void Update() { if (m_hostId == -1) return; int connectionId; int channelId; byte[] buffer = new byte[1500]; int receivedSize; byte error; NetworkEventType networkEvent = NetworkTransport.ReceiveFromHost(m_hostId, out connectionId, out channelId, buffer, 1500, out receivedSize, out error); if (networkEvent == NetworkEventType.Nothing) return; receiveLabel += string.Format("{0} connectionId {1} channelId {2} receivedSize {3}\n", networkEvent.ToString(), connectionId, channelId, receivedSize); // If someone connected then save this info if (networkEvent == NetworkEventType.ConnectEvent) { string address; int port; UnityEngine.Networking.Types.NetworkID network; UnityEngine.Networking.Types.NodeID dstNode; NetworkTransport.GetConnectionInfo(m_hostId, connectionId, out address, out port, out network, out dstNode, out error); receiveLabel += string.Format("address {0} port {1}\n", address, port); connectionDictionary.Add(connectionId, new IPEndPoint(IPAddress.Parse(address), port)); } else if (networkEvent == NetworkEventType.DisconnectEvent) // Remove from connection list { connectionDictionary.Remove(connectionId); } else if (networkEvent == NetworkEventType.DataEvent) { // Echo to everyone what we just received foreach (var pair in connectionDictionary) { NetworkTransport.Send(m_hostId, pair.Key, reliableChannel, buffer, receivedSize, out error); } } } }
If this helped you out or you can think of any improvements or things I did wrong, please let me know. Thanks.