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.
