-
Star
(170)
You must be signed in to star a gist -
Fork
(31)
You must be signed in to fork a gist
-
-
Save danielbierwirth/0636650b005834204cb19ef5ae6ccedb to your computer and use it in GitHub Desktop.
// This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. | |
// To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/ | |
// or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. | |
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Net.Sockets; | |
using System.Text; | |
using System.Threading; | |
using UnityEngine; | |
public class TCPTestClient : MonoBehaviour { | |
#region private members | |
private TcpClient socketConnection; | |
private Thread clientReceiveThread; | |
#endregion | |
// Use this for initialization | |
void Start () { | |
ConnectToTcpServer(); | |
} | |
// Update is called once per frame | |
void Update () { | |
if (Input.GetKeyDown(KeyCode.Space)) { | |
SendMessage(); | |
} | |
} | |
/// <summary> | |
/// Setup socket connection. | |
/// </summary> | |
private void ConnectToTcpServer () { | |
try { | |
clientReceiveThread = new Thread (new ThreadStart(ListenForData)); | |
clientReceiveThread.IsBackground = true; | |
clientReceiveThread.Start(); | |
} | |
catch (Exception e) { | |
Debug.Log("On client connect exception " + e); | |
} | |
} | |
/// <summary> | |
/// Runs in background clientReceiveThread; Listens for incomming data. | |
/// </summary> | |
private void ListenForData() { | |
try { | |
socketConnection = new TcpClient("localhost", 8052); | |
Byte[] bytes = new Byte[1024]; | |
while (true) { | |
// Get a stream object for reading | |
using (NetworkStream stream = socketConnection.GetStream()) { | |
int length; | |
// Read incomming stream into byte arrary. | |
while ((length = stream.Read(bytes, 0, bytes.Length)) != 0) { | |
var incommingData = new byte[length]; | |
Array.Copy(bytes, 0, incommingData, 0, length); | |
// Convert byte array to string message. | |
string serverMessage = Encoding.ASCII.GetString(incommingData); | |
Debug.Log("server message received as: " + serverMessage); | |
} | |
} | |
} | |
} | |
catch (SocketException socketException) { | |
Debug.Log("Socket exception: " + socketException); | |
} | |
} | |
/// <summary> | |
/// Send message to server using socket connection. | |
/// </summary> | |
private void SendMessage() { | |
if (socketConnection == null) { | |
return; | |
} | |
try { | |
// Get a stream object for writing. | |
NetworkStream stream = socketConnection.GetStream(); | |
if (stream.CanWrite) { | |
string clientMessage = "This is a message from one of your clients."; | |
// Convert string message to byte array. | |
byte[] clientMessageAsByteArray = Encoding.ASCII.GetBytes(clientMessage); | |
// Write byte array to socketConnection stream. | |
stream.Write(clientMessageAsByteArray, 0, clientMessageAsByteArray.Length); | |
Debug.Log("Client sent his message - should be received by server"); | |
} | |
} | |
catch (SocketException socketException) { | |
Debug.Log("Socket exception: " + socketException); | |
} | |
} | |
} |
// This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. | |
// To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/ | |
// or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. | |
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Net; | |
using System.Net.Sockets; | |
using System.Text; | |
using System.Threading; | |
using UnityEngine; | |
public class TCPTestServer : MonoBehaviour { | |
#region private members | |
/// <summary> | |
/// TCPListener to listen for incomming TCP connection | |
/// requests. | |
/// </summary> | |
private TcpListener tcpListener; | |
/// <summary> | |
/// Background thread for TcpServer workload. | |
/// </summary> | |
private Thread tcpListenerThread; | |
/// <summary> | |
/// Create handle to connected tcp client. | |
/// </summary> | |
private TcpClient connectedTcpClient; | |
#endregion | |
// Use this for initialization | |
void Start () { | |
// Start TcpServer background thread | |
tcpListenerThread = new Thread (new ThreadStart(ListenForIncommingRequests)); | |
tcpListenerThread.IsBackground = true; | |
tcpListenerThread.Start(); | |
} | |
// Update is called once per frame | |
void Update () { | |
if (Input.GetKeyDown(KeyCode.Space)) { | |
SendMessage(); | |
} | |
} | |
/// <summary> | |
/// Runs in background TcpServerThread; Handles incomming TcpClient requests | |
/// </summary> | |
private void ListenForIncommingRequests () { | |
try { | |
// Create listener on localhost port 8052. | |
tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 8052); | |
tcpListener.Start(); | |
Debug.Log("Server is listening"); | |
Byte[] bytes = new Byte[1024]; | |
while (true) { | |
using (connectedTcpClient = tcpListener.AcceptTcpClient()) { | |
// Get a stream object for reading | |
using (NetworkStream stream = connectedTcpClient.GetStream()) { | |
int length; | |
// Read incomming stream into byte arrary. | |
while ((length = stream.Read(bytes, 0, bytes.Length)) != 0) { | |
var incommingData = new byte[length]; | |
Array.Copy(bytes, 0, incommingData, 0, length); | |
// Convert byte array to string message. | |
string clientMessage = Encoding.ASCII.GetString(incommingData); | |
Debug.Log("client message received as: " + clientMessage); | |
} | |
} | |
} | |
} | |
} | |
catch (SocketException socketException) { | |
Debug.Log("SocketException " + socketException.ToString()); | |
} | |
} | |
/// <summary> | |
/// Send message to client using socket connection. | |
/// </summary> | |
private void SendMessage() { | |
if (connectedTcpClient == null) { | |
return; | |
} | |
try { | |
// Get a stream object for writing. | |
NetworkStream stream = connectedTcpClient.GetStream(); | |
if (stream.CanWrite) { | |
string serverMessage = "This is a message from your server."; | |
// Convert string message to byte array. | |
byte[] serverMessageAsByteArray = Encoding.ASCII.GetBytes(serverMessage); | |
// Write byte array to socketConnection stream. | |
stream.Write(serverMessageAsByteArray, 0, serverMessageAsByteArray.Length); | |
Debug.Log("Server sent his message - should be received by client"); | |
} | |
} | |
catch (SocketException socketException) { | |
Debug.Log("Socket exception: " + socketException); | |
} | |
} | |
} |
How to use in the case where I'm sending object
I know that I should serialize it but while deserializing it I have a problem in the fonction of deserialization
Show this error :
FromJsonOverwite can only be called from the main thread.
What should I do!?
Thanks for the code. I used the C# example for the client in Unity and wrote a server in Python. However I have problems with the rate at which I can send messages from the server to the client. I get BrokenPipeErrors when the rate is too fast. Maybe something about the ListenForData
function in the client can be improved
The tcp port connection is not being freed since the client and server are running a background thread that only gets finished after closing or reloading the Editor (not totally sure about the last one), not after exiting play mode. So in order to reset the connection properly, call Close() on the server and the client, and make sure the threads can finish, adding a different condition inside the while(true) loops
Is while true loop necessary? I found that disposable getstream usage closes that socket, so next iteration of while loop throws exception dur to closed socket.
@ Send message to server
Servers expect an end of line after the text message. In my case a CR. Therefore, the code for the TCP client private void SendMessage() looks like this:
byte[] clientMessageAsByteArray = Encoding.ASCII.GetBytes(clientMessage + “\r”);
I couldn't make the server work on Unity 2020.3. I tested several clients and but I couldn't connect (timeout). Then I changed
IPAddress.Parse("127.0.0.1")
toIPAddress.Any
when creating the TcpListener and now everything works flawless.