How to do a TCP Server?

Hi guys, I think my last question was misinterpreted, so here is a more simple one.

How to create a TCP server and Client in unity? I don’t want to use unity network layer, this game will connect to a C++ server so I need it to talk to this server someway.

I’m completely lost, all my tries resulted in failure.

Edit:

This the code that is problematic, whenever i call "Socket soc = listener.AcceptSocket();"Unity crashes, I’ve tried putting it inside a coroutine without sucess.

using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Net.Sockets;

public class ServerClass : MonoBehaviour
{
	TcpListener listener;
	
	public void Start()
	{
		listener = new TcpListener(2033);
		listener.Start();
	}
	
	public void Update()
	{
            if(!listener.Pending())
		{
			Debug.Log("Nothing to do here");
		}
		else
		{
		
		Socket soc = listener.AcceptSocket();

                [...]
            }
       }
}

AcceptSocket is a blocking call - you don’t want to be calling that unless you know that there is a request pending - you can tell that using this. Otherwise Unity will hang until a request appears.

Coroutines are not threads - a coroutine that blocks will lock up Unity.

Ok so you can use my Loom class to interact with other thread (per the comments to my answer above - this is too long to be a comment) which lets you do this:

 void Update()  {
     if(somethingHappened) 
     {
       Loom.RunAsync(()=>{
            //Your other thread code goes here
            //e.g. SendStuff();



            //If you need to then call back to the game
            Loom.QueueOnMainThread(()=>{
                  //Code triggered from the other thread that
                  //accesses Unity object goes here
               });
       });
    }
}

#Loom.cs#

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Threading;
using System.Linq;
			
//Loom handles threading
public class Loom : MonoBehaviour
{
	private static Loom _current;
		
	public static Loom Current
	{
		get
		{
			if (_current == null && Application.isPlaying)
			{
			    
				var g = GameObject.Find("Loom");
				if(g==null)
				{
					g = new GameObject("Loom");
					g.hideFlags = HideFlags.HideAndDontSave;
				}
				
				_current = g.GetComponent<Loom>() ?? g.AddComponent<Loom>();
			}
						
			return _current;
		}
	}
	
	void Awake()
	{
		if(_current != null && _current != this)
		{
			DestroyImmediate(gameObject);
		}
		else
		{
			_current = this;
		}
	}
		
	private List<Action> _actions = new List<Action>();
	public class DelayedQueueItem
	{
		public float time;
		public Action action;
		public string name;
	}
	private List<DelayedQueueItem> _delayed = new  List<DelayedQueueItem>();
				
	public static void QueueOnMainThread(Action action, float time, string name)
	{
		lock(Current._delayed)
		{
			if(Current._delayed.Any(d=>d.name==name))
				return;
			QueueOnMainThread(action, time);
		}
	}
	
	public static void QueueOnMainThread(Action action, string name)
	{
		QueueOnMainThread(action, 0, name);
	}
	
	public static void QueueOnMainThread(Action action, float time)
	{
		if (time != 0)
		{
			lock (Current._delayed)
			{
				Current._delayed.Add(new DelayedQueueItem { time = Time.time + time, action = action});
			}
		}
		else
		{
			lock (Current._actions)
			{
				Current._actions.Add(action);
			}
		}
	}
	
	public static void QueueOnMainThread(Action action)
	{
		lock (Current._actions)
		{
			Current._actions.Add(action);
		}
	}
				
	public static void RunAsync(Action a)
	{
		var t = new Thread(RunAction);
		t.Priority = System.Threading.ThreadPriority.Normal;
		t.Start(a);
	}
				
	private static void RunAction(object action)
	{
		((Action)action)();
	}
	
				
	Action[] toBeRun = new Action[1000];
	DelayedQueueItem[] toBeDelayed = new DelayedQueueItem[1000];
	
	void Update()
	{
		try
		{
			var actions = 0;
			var delayedCount = 0;
			//Process the non-delayed actions
			lock (_actions)
			{
				for(var i = 0; i < _actions.Count; i++)
				{
					toBeRun[actions++] = _actions*;*
  •  			if(actions==999)*
    
  •  				break;*
    
  •  		}*
    
  •  		_actions.Clear();*
    
  •  	}*
    
  •  	for(var i = 0; i < actions; i++)*
    
  •  	{*
    

_ var a = toBeRun*;_
_
try _
_
{_
_
a();_
_
}_
_
catch (Exception e)_
_
{_
_
Debug.LogError("Queued Exception: " + e.ToString());_
_
}_
_
}_
lock (delayed)
_
{*

* for(var i = 0; i <delayed.Count; i++)
_
{*

var d = delayed*;*
* if(d.time < Time.time)
{
toBeDelayed[delayedCount++]= d;
if(delayedCount==999)
break;
}
}
}
for(var i = 0; i < delayedCount; i++)
{
var delayed = toBeDelayed;_

lock (delayed)*
* {_
delayed.Remove(delayed);*
* }
try*

* {
delayed.action();
}
catch (Exception e)
{
Debug.LogError(“Delayed Exception:” + e.ToString());
}
}*_

* }*
* catch(Exception e)*
* {*
* Debug.LogError("Loom Error " + e.ToString());*
* }*
* }*
}

Check this brilliant presentation. There is a chapter with full example based on .net sockets, server and client side. Very clean and easy code. You will realize why async socket operations like BeginConnect, BeginReceive and so are needed to make it running with Unity.

http://video.unity3d.com/video/6947115/unite-2012-unity-network

UPDATE: somehow original ^^^ video not available anymore, so mirror:

If you are going to connect to a C++ Server, why do you want to create a TCP server in Unity? And since you don’t want to use the Unity network layer, this is not a Unity question any more.

Anyway, the answer is “Use a socket API you like.” Let me google this for you… like this one: Socket Class (System.Net.Sockets) | Microsoft Learn

Hope it helps.