1. Code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
public delegate void ConnectCallBack();
public delegate void TCPRecvCallBack(string msg);
public class AnTCP
{
public enum TCPMode
{
Client,//客户端
Server//服务端
}
private int TcpPort;
private Socket TcpSocket;
private Socket TcpClient;
private EndPoint ServerPoint;
private TCPMode Mode;
//
private Thread OpenThread;//监听(链接)线程
private Thread RecvThread;//接收线程
//call back
private ConnectCallBack ConnectCall;
private TCPRecvCallBack RecvCallBack;//回调函数
public AnTCP()
{
TcpPort = 0;
}
public bool Open(TCPMode _mode,int _port,string _ip, ConnectCallBack _call)
{
Mode = _mode;
TcpPort = _port;
TcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
if(Mode == TCPMode.Client)
{
ServerPoint = new IPEndPoint(IPAddress.Parse(_ip), TcpPort);
if (OpenThread != null)
{
OpenThread.Abort();
OpenThread.Interrupt();
OpenThread = null;
}
OpenThread = new Thread(OnConnectToServer);
OpenThread.Start();
//
ConnectCall = _call;
}
else if(Mode == TCPMode.Server)
{
//绑定端口和网络地址
ServerPoint = new IPEndPoint(IPAddress.Parse(_ip), TcpPort);
TcpSocket.Bind(ServerPoint);
//最大连接数
TcpSocket.Listen(5);
//开启线程
if(OpenThread != null)
{
OpenThread.Abort();
OpenThread.Interrupt();
OpenThread = null;
}
OpenThread = new Thread(OnWaitForClient);
OpenThread.Start();
//
ConnectCall = _call;
}
return true;
}
public void Close()
{
if (OpenThread != null)
{
OpenThread.Abort();
OpenThread.Interrupt();
OpenThread = null;
}
if (RecvThread != null)
{
RecvThread.Abort();
RecvThread.Interrupt();
RecvThread = null;
}
if (TcpSocket != null)
{
TcpSocket.Close();
}
if (TcpClient!=null)
{
TcpClient.Close();
}
}
public bool Send(string msg)
{
if (TcpSocket == null) return false;
byte[] sendData = Encoding.ASCII.GetBytes(msg);
if (Mode == TCPMode.Client)
TcpSocket.Send(sendData);
else if (Mode == TCPMode.Server)
TcpClient.Send(sendData);
return true;
}
public void StartRecv(TCPRecvCallBack _call)
{
RecvCallBack = _call;
}
private void OnConnectToServer()
{
while (true)
{
try
{
TcpSocket.Connect(ServerPoint);
if (RecvThread != null)
{
RecvThread.Abort();
RecvThread.Interrupt();
RecvThread = null;
}
RecvThread = new Thread(ClientReceive);
RecvThread.Start();
if (ConnectCall != null)
{
ConnectCall();
}
OpenThread.Abort();
return;
}
catch (Exception e)
{
}
}
}
private void OnWaitForClient()
{
while(true)
{
try
{
TcpClient = TcpSocket.Accept();
if (RecvThread != null)
{
RecvThread.Abort();
RecvThread.Interrupt();
RecvThread = null;
}
RecvThread = new Thread(ServerReceive);
RecvThread.Start();
if (ConnectCall != null)
{
ConnectCall();
}
}
catch (Exception e)
{
}
}
}
private void ClientReceive()
{
while (true)
{
try
{
byte[] recvData = new byte[1024];
//接收
int recvLen = TcpSocket.Receive(recvData);
if (recvLen > 0)
{
string data = Encoding.ASCII.GetString(recvData, 0, recvLen);
if (RecvCallBack != null)
{
RecvCallBack(data);
}
}
}
catch (Exception e)
{
}
}
}
private void ServerReceive()
{
while (true)
{
try
{
byte[] recvData = new byte[1024];
//接收
int recvLen = TcpClient.Receive(recvData);
if (recvLen > 0)
{
string data = Encoding.ASCII.GetString(recvData, 0, recvLen);
if (RecvCallBack != null)
{
RecvCallBack(data);
}
}
}
catch (Exception e)
{
}
}
}
}
Two, use
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Controller : MonoBehaviour
{
public Text Log;
private AnTCP TCP;
private List<string> SockOrders;
// Start is called before the first frame update
void Start()
{
TCP = new AnTCP();
TCP.Open(AnTCP.TCPMode.Server, 9000, "127.0.0.1", OnConnected);
SockOrders = new List<string>();
}
// Update is called once per frame
void Update()
{
if(SockOrders.Count!=0)
{
Log.text = SockOrders[0];
SockOrders.RemoveAt(0);
}
}
void OnApplicationQuit()
{
TCP.Close();
}
private void OnConnected()
{
TCP.Send("Hello");
TCP.StartRecv(OnRecved);
}
private void OnRecved(string msg)
{
SockOrders.Add(msg);
}
}
3. Remarks
1. Only 1-to-1 link is supported, and the receiving and sending of the server are the last ones
2. Use ASCII