分为两个Unity项目
一个是SeverTest01 用于Unity的服务器部分
一个是SocketTest01 用于Unity的客户端部分 关于客户端部分的
初步学习只有简单的服务器和客户端连接,并且发送消息回复,算是一个学习记录
关于端口
0-65535其中0-1023叫做周知端口我们不能使用,这里使用的是10086端口,服务器端和客户端端口要一致才能连接得上
0-1023叫做周知端口
动态端口的范围是从49152到65535
注册端口端口1024到49151
代码展示
SeverTest01 部分 新建场景001 将Server挂到Camera上即可
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System;
/// <summary>
/// 可以供客户端和服务器一块使用
/// </summary>
public class TcpSocket
{
//当前实例化的socket
private Socket socket;
//socket上的数据
private byte[] data;
//区分服务器 还是客户端
private bool isServer;
public TcpSocket(Socket socket, int dataLength, bool isServer)
{
this.socket = socket;
data = new byte[dataLength];
this.isServer = isServer;
}
#region 接受
public void ClientReceive()
{
//data 数据缓存 0:指的是 接受位的偏移量 data.length指的是数据的长度 SocketFlags.None固定格式
//new AsyncCallback(ClientEndReceive)需要有返回值的回调函数,返回值是下面的方法
//public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state);
socket.BeginReceive(data, 0, data.Length, SocketFlags.None, new AsyncCallback(ClientEndReceive), null);
}
public void ClientEndReceive(IAsyncResult ar)
{
//数据的处理
int receiveLength = socket.EndReceive(ar); //将接受到的数据赋值给receiveLength
//把接受完毕的字节数组转化为 string类型
string dataStr = System.Text.Encoding.UTF8.GetString(data, 0, receiveLength);
if (isServer) //判断是否接收到了因为开始设定了isServer是布尔值
{
Debug.Log("服务器接受到了:" + dataStr);
//服务器要回什么
for (int i = 0; i < Server.Instance.clients.Count; i++)
{
if (Server.Instance.clients[i].ClientConnect())
{
Server.Instance.clients[i].ClientSeed(System.Text.Encoding.UTF8.GetBytes( "服务器回复:是的"));
//Server.Instance.clients[i].ClientSeed(System.Text.Encoding.UTF8.GetBytes("服务器收到了客户端发送的:" + dataStr));
}
}
}
else
{
Debug.Log("客户端接受到了:" + dataStr);
}
}
#endregion
#region 发送
public void ClientSeed(byte[] data) //这里发送的是byte的字节
{
socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(ClientSeedEnd), null);
}
private void ClientSeedEnd(IAsyncResult ar)
{
socket.EndSend(ar);
}
#endregion
#region 连接
public void ClientConnect(string ip, int port)
{
socket.BeginConnect(new IPEndPoint(IPAddress.Parse(ip), port), new AsyncCallback(ClientEndConnect), null);
}
public void ClientEndConnect(IAsyncResult ar)
{
if (ar.IsCompleted)
{
Debug.Log("连接成功");
}
socket.EndConnect(ar);
}
#endregion
#region 断开
public bool ClientConnect()
{
return socket.Connected;
}
#endregion
}
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System;
using UnityEngine;
using UnityEngine.UI;
public class Client : MonoBehaviour {
//public Button sendBtn;//发送给服务器按钮
//public Button connectBtn;//连接服务器按钮
public InputField input;
public Text receiveText;
TcpSocket tcpClient;
// Use this for initialization
void Start () {
Socket client = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
tcpClient = new TcpSocket(client,1024,false);
}
// Update is called once per frame
void Update () {
if (tcpClient!=null&&tcpClient.ClientConnect())
{
tcpClient.ClientReceive();
}
}
public void OnClickConnectBtn()
{
if (!tcpClient.ClientConnect())
{
tcpClient.ClientConnect("10.50.6.129",10086);
}
}
public void OnClickToSendServer()
{
if (tcpClient != null && tcpClient.ClientConnect() && !String.IsNullOrEmpty(input.text))
{
tcpClient.ClientSeed(System.Text.Encoding.UTF8.GetBytes(input.text));
input.text = "";
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System;
/// <summary>
/// 服务器
/// </summary>
public class Server : MonoBehaviour {
private static Server instance;
public static Server Instance
{
get {
return instance;
}
}
private void Awake()
{
instance = this;
}
private Socket server;
//所有连接的客户端
public List<TcpSocket> clients;
private bool isLoopAccept = true;
// Use this for initialization
void Start ()
{
// 服务器socket 协议族
server = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//绑定端口号
server.Bind(new IPEndPoint(IPAddress.Any,10086));
//可以监听的客户端数目
server.Listen(100);
//开辟一个线程 处理客户端连接请求
Thread listenThread = new Thread(ReceiveClient);
//开启线程
listenThread.Start();
//后台运行
listenThread.IsBackground = true;
clients = new List<TcpSocket>();
}
/// <summary>
/// 接受客户端连接的请求
/// </summary>
private void ReceiveClient()
{
while (isLoopAccept)
{
//开始接受客户端连接请求
server.BeginAccept(AcceptClient,null);
Debug.Log("检测客户端连接中.....");
//每隔1s检测 有没有连接我
Thread.Sleep(1000);
}
}
private void OnApplicationQuit()
{
isLoopAccept = false;
if (server != null && server.Connected)
{
server.Close();
}
}
/// <summary>
/// 客户端连接成功之后得回调
/// </summary>
/// <param name="ar"></param>
private void AcceptClient(IAsyncResult ar)
{
Socket client = server.EndAccept(ar);
TcpSocket clientSocket = new TcpSocket(client,1024,true);
clients.Add(clientSocket);
Debug.Log("连接成功");
}
private void Update()
{
if (clients!=null&& clients.Count>=0)
{
for (int i = 0; i < clients.Count; i++)
{
//监听每个服务器(连接的)发送的信息
clients[i].ClientReceive();
}
}
}
}
附项目部分(项目链接:https://pan.baidu.com/s/16bi4JKJOmEqIom8Nnxv62A 提取码:gkr5 )