服务器端框架
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using PB;
using Google.Protobuf;
namespace ConsoleApp1
{
public class Client
{
public Socket socket;
public string ip;
public byte[] data = new byte[1024];
public byte[] syarr = new byte[0];
public PlayDate play;
}
class NetManager:Singleton<NetManager>
{
Socket socket;
public List<Client> clients = new List<Client>();
/// <summary>
/// 初始化
/// </summary>
public void Init()
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iP = new IPEndPoint(IPAddress.Any, 12345);
socket.Bind(iP);
socket.Listen(5);
socket.BeginAccept(OnAccept, null);
}
private void OnAccept(IAsyncResult ar)
{
Socket client = socket.EndAccept(ar);
//ip地址
IPEndPoint iP = client.RemoteEndPoint as IPEndPoint;
Client cli = new Client();
cli.socket = client;
cli.ip = iP.Address + ":" + iP.Port;
clients.Add(cli);
Console.WriteLine(cli.ip);
//接受消息
cli.socket.BeginReceive(cli.data, 0, cli.data.Length, SocketFlags.None, OnReceive, cli);
//开启下一次连接
socket.BeginAccept(OnAccept, null);
}
/// <summary>
/// 接受客户端消息
/// </summary>
/// <param name="ar"></param>
private void OnReceive(IAsyncResult ar)
{
Client cli = ar.AsyncState as Client;
int length = cli.socket.EndReceive(ar);
if (length<=0)
{
cli.socket.Shutdown(SocketShutdown.Both);
cli.socket.Close();
clients.Remove(cli);
foreach (var item in clients)
{
MessageCenter.Instance.BroadCast(MsgID.C2S_Leave, cli.play.ToByteArray(), item);
MessageCenter.Instance.BroadCast(MsgID.C2S_Destory, cli.play.ToByteArray(), item);
Console.WriteLine("下线");
}
}
else
{
byte[] newarr = new byte[cli.syarr.Length + length];
Buffer.BlockCopy(cli.syarr, 0, newarr, 0, cli.syarr.Length);
Buffer.BlockCopy(cli.data, 0, newarr, cli.syarr.Length, length);
while (newarr.Length>=2)
{
int cont = BitConverter.ToUInt16(newarr, 0);
if (newarr.Length>=cont+4)
{
int id = BitConverter.ToUInt16(newarr, 2);
byte[] body = new byte[cont];
Buffer.BlockCopy(newarr, 4, body, 0, body.Length);
MessageCenter.Instance.BroadCast(id, body, cli);
//剩余长度
int sylength = newarr.Length - (cont + 4);
if (sylength>0)
{
byte[] sydata = new byte[sylength];
Buffer.BlockCopy(newarr, cont + 4, sydata, 0, sylength);
newarr = sydata;
}
else
{
cli.syarr = new byte[0];
break;
}
}
else
{
cli.syarr = newarr;
break;
}
}
cli.socket.BeginReceive(cli.data, 0, cli.data.Length, SocketFlags.None, OnReceive, cli);
}
}
/// <summary>
/// 发送消息
/// </summary>
/// <param name="cli"></param>
/// <param name="id"></param>
/// <param name="body"></param>
public void Send(Client cli,int id,byte[] body)
{
byte[] cont = BitConverter.GetBytes((ushort)body.Length);
byte[] head = BitConverter.GetBytes((ushort)id);
byte[] arr = cont.Concat(head.Concat(body).ToArray()).ToArray();
if (cli.socket.Connected)
{
cli.socket.BeginSend(arr, 0, arr.Length, SocketFlags.None, OnSend, cli);
}
}
private void OnSend(IAsyncResult ar)
{
Client cli = ar.AsyncState as Client;
if (cli.socket.Connected)
{
int length = cli.socket.EndSend(ar);
Console.WriteLine("消息长度:" + length);
}
}
}
}
客户端框架
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Linq;
using System.Text;
using System;
public class NetManager
{
static Socket socket;
static byte[] data = new byte[1024];
static byte[] syarr = new byte[0];
static Queue<byte[]> que = new Queue<byte[]>();
public static void Init()
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.BeginConnect("127.0.0.1", 12345, OnConnect, null);
}
/// <summary>
/// 连接服务器
/// </summary>
/// <param name="ar"></param>
private static void OnConnect(IAsyncResult ar)
{
socket.EndConnect(ar);
//接受消息
socket.BeginReceive(data, 0, data.Length, SocketFlags.None, OnReceive, null);
}
private static void OnReceive(IAsyncResult ar)
{
int length = socket.EndReceive(ar);
if (length<=0)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
else
{
byte[] newarr = new byte[syarr.Length + length];
Buffer.BlockCopy(syarr, 0, newarr, 0, syarr.Length);
Buffer.BlockCopy(data, 0, newarr, syarr.Length, length);
while (newarr.Length>=2)
{
int cont = BitConverter.ToUInt16(newarr, 0);
if (newarr.Length>=cont+4)
{
byte[] body = new byte[cont + 2];
Buffer.BlockCopy(newarr, 2, body, 0, body.Length);
que.Enqueue(body);
//剩余长度
int sylength = newarr.Length - (cont + 4);
if (sylength>0)
{
byte[] sydata = new byte[sylength];
Buffer.BlockCopy(newarr, cont + 4, sydata,0,sylength);
newarr = sydata;
}
else
{
syarr = new byte[0];
break;
}
}
else
{
syarr = newarr;
break;
}
}
socket.BeginReceive(data, 0, data.Length, SocketFlags.None, OnReceive, null);
}
}
public static void UpDate()
{
while (que.Count>0)
{
byte[] arr = que.Dequeue();
int id = BitConverter.ToUInt16(arr, 0);
byte[] body = new byte[arr.Length - 2];
Buffer.BlockCopy(arr, 2, body, 0, body.Length);
MessageCenter.Instance.BroadCast(id, body);
}
}
public static void Send(int id,byte[] body)
{
byte[] cont = BitConverter.GetBytes((ushort)body.Length);
byte[] head = BitConverter.GetBytes((ushort)id);
byte[] arr = cont.Concat(head.Concat(body).ToArray()).ToArray();
socket.BeginSend(arr, 0, arr.Length, SocketFlags.None, OnSend, null);
}
private static void OnSend(IAsyncResult ar)
{
int length = socket.EndSend(ar);
Debug.Log("消息长度:" + length);
}
public static void Close()
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}