远程需要联网的在上一篇:https://blog.csdn.net/qq_35864875/article/details/126873640?spm=1001.2014.3001.5501
这个是需要自己写服务端的局域网内使用的Socket
服务端代码:
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Newtonsoft.Json;
using UnityEngine;
namespace UnityServer
{
class NetworkServer : MonoBehaviour
{
private static Socket serverSocket;
private static byte[] buffer = new byte[1024];
private void Awake()
{
Main();
}
static void Main()
{
/*创建一个socket对象*/
//寻址方式 套接字类型 协议方式
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
/*绑定监听消息IP和端口号*/
serverSocket.Bind(new IPEndPoint(IPAddress.Any, 6000));//IPAddress.Any代表本机IP
Debug.Log("服务器端启动完成");
/*开始监听客户端的连接请求*/
serverSocket.Listen(100);//最多可以接收100个客户端请求
StartAccept();//接收客户端连接
Console.Read();//从标准输入流中读取下一个字符。当用户键入一些输入字符时,此方法基本上阻止其返回。一旦用户按ENTER键,它就会终止。
}
private void OnDestroy()
{
Close();
}
void Close()
{
serverSocket.Close();
Debug.Log("socket关闭了");
}
//接收客户端连接
static void StartAccept()
{
serverSocket.BeginAccept(AcceptCallback, null);
}
//接收客户端消息
static void StartReceive(Socket socket)
{
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallback, socket);
}
static void ReceiveCallback(IAsyncResult iar)
{
Socket socket = iar.AsyncState as Socket;
int messgeLength = socket.EndReceive(iar);
if (messgeLength == 0)
{
return;
}
//将接收的消息转化为string类型
string str = Encoding.UTF8.GetString(buffer, 0, messgeLength);
try
{
//代理调用主线程的方法(这个Socket 创建的是子线程无法调用到主线程的东西所以需要中介代理)
Invoker.InvokeInMainThread(() =>
{
//Debug.Log(str);//打印接收的消息
});
}
catch (Exception e)
{
Debug.Log("接收内容非字符串" + e.Message);
}
StartReceive(socket);//循环调用本函数,一直接收消息
}
static void AcceptCallback(IAsyncResult iar)
{
Socket socket = serverSocket.EndAccept(iar);
Debug.Log("有个客户端连接过来了");
Send(socket, "你好,我是服务器");
StartReceive(socket);
StartAccept();//循环调用本函数,一直接收客户端连接
}
//向客户端发消息
static void Send(Socket socket, string str)
{
str = "由服务端发送:" + str;
var date = ASCIIEncoding.UTF8.GetBytes(str);
socket.Send(date);
}
}
}
客户端的代码:
using UnityEngine;
using System.Collections;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System;
public class NetworkClient : MonoBehaviour
{
private Socket clientSocket;//声明Socket
private byte[] buffer = new byte[1024];
public static NetworkClient Ins;
public bool IsConnected = false;//是否已连接的标识
private void Awake()
{
Ins = this;
}
void Start()
{
//创建socket
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//连接服务器
IPEndPoint ip_end_point = new IPEndPoint(IPAddress.Parse("192.168.2.32"), 6000);
try
{
clientSocket.Connect(ip_end_point);
IsConnected = true;
Debug.Log("连接服务器成功");
}
catch
{
IsConnected = false;
Debug.Log("连接服务器失败");
return;
}
//开始接收消息
StartReceive();
//发送一条消息给服务器
//Send("我是客户端");
}
//接收消息
void StartReceive()
{
clientSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallback, null);
}
void ReceiveCallback(IAsyncResult iar)
{
int messgeLength = clientSocket.EndReceive(iar);
if (messgeLength == 0)
{
return;
}
//将接收的消息转化为string类型
string str = Encoding.UTF8.GetString(buffer, 0, messgeLength);
Debug.Log(str);//打印接收的消息
StartReceive();//循环调用本函数,一直接收消息
}
//发送消息
public void Send(string str)
{
if (IsConnected == false)
{
clientSocket.Send(ASCIIEncoding.UTF8.GetBytes(str));
}
else
{
Debug.Log("客户端未连接");
}
}
}
最后是调用主线程的中介代码:
下面这个脚本挂载在空物体上面 同时勾选是否是服务端 脚本会根据判断Add上面俩个类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityServer;
public class Invoker : MonoBehaviour
{
//是否是服务端
public bool isSocketTcpServer = true;
public static Invoker Ins;
public static void InvokeInMainThread(System.Action _delegate)
{ Ins.delegates.Add(_delegate); }
public List<System.Action> delegates = new List<System.Action>();
private void Awake()
{
Ins = this;
if (isSocketTcpServer)
{
gameObject.AddComponent<NetworkServer>();
}
else
{
gameObject.AddComponent<NetworkClient>();
}
}
void Update()
{ Execute(); }
void Execute()
{
if (delegates.Count == 0)
return;
for (int i = 0; i < delegates.Count; i++)
delegates[i]();
delegates.Clear();
}
}