Unity C# 网络学习(五)
一.简单的异步服务器搭建
1.ClientSocket
namespace TcpAsyncServer
{
class ClientSocket
{
public Socket socket;
public int id;
private static int CURR_Client_ID = 0;
private byte[] _buffer = new byte[1024];
private int _cacheNum = 0;
public ClientSocket(Socket socket)
{
this.socket = socket;
id = CURR_Client_ID++;
ReceiveAsync();
}
private void ReceiveAsync()
{
socket.BeginReceive(_buffer, _cacheNum, _buffer.Length, SocketFlags.None, ReceiveAsyncCallBack, null);
}
private void ReceiveAsyncCallBack(IAsyncResult ar)
{
try
{
_cacheNum = socket.EndReceive(ar);
Console.WriteLine(Encoding.UTF8.GetString(_buffer, 0, _cacheNum));
_cacheNum = 0;
if (socket.Connected)
socket.BeginReceive(_buffer, _cacheNum, _buffer.Length, SocketFlags.None, ReceiveAsyncCallBack, null);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public void SendMsg(string msg)
{
var buffer = Encoding.UTF8.GetBytes(msg);
socket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, SendMsgAsyncCallBack, null);
}
private void SendMsgAsyncCallBack(IAsyncResult ar)
{
try
{
socket.EndSend(ar);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
2.ServerSocket
namespace TcpAsyncServer
{
class ServerSocket
{
private Dictionary<int, ClientSocket> _allClientSockets;
private Socket socket;
public ServerSocket()
{
_allClientSockets = new Dictionary<int, ClientSocket>();
}
public void Start(string ip,int host)
{
if (socket != null && socket.Connected)
return;
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
socket.Bind(new IPEndPoint(IPAddress.Parse(ip), host));
socket.Listen(10);
socket.BeginAccept(AcceptAsyncCallBack, null);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
private void AcceptAsyncCallBack(IAsyncResult ar)
{
try
{
var newSocket = socket.EndAccept(ar);
var newClientSocket = new ClientSocket(newSocket);
_allClientSockets.Add(newClientSocket.id, newClientSocket);
socket.BeginAccept(AcceptAsyncCallBack, null);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public void Broadcast(string msg)
{
foreach (var client in _allClientSockets.Values)
client.SendMsg(msg);
}
}
}
namespace TcpAsyncServer
{
class Program
{
static void Main(string[] args)
{
var serverSocket = new ServerSocket();
serverSocket.Start("127.0.0.1", 8080);
Console.WriteLine("服务器开启成功!");
while (true)
{
var input = Console.ReadLine();
if (input.Substring(0, 2) == "s:")
{
serverSocket.Broadcast(input.Substring(2));
}
}
}
}
}
二.简单的异步客户端搭建
public class NetAsyncMgr : MonoBehaviour
{
public static NetAsyncMgr Instance;
private Socket _socket;
private byte[] _buffer = new byte[1024 * 1024];
private void Awake()
{
Instance = this;
}
public void Connect(string ip, int host)
{
if (_socket != null)
return;
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var args = new SocketAsyncEventArgs();
args.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(ip), host);
args.Completed += (sender, eventArgs) =>
{
if (eventArgs.SocketError == SocketError.Success)
{
var recEventArgs = new SocketAsyncEventArgs();
recEventArgs.SetBuffer(_buffer, 0, _buffer.Length);
recEventArgs.Completed += ReceiveCallBack;
this._socket.ReceiveAsync(recEventArgs);
}
else
{
Debug.LogError("连接失败!" + eventArgs.SocketError);
}
};
_socket.ConnectAsync(args);
}
private void ReceiveCallBack(object sender, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
Debug.Log(Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred));
e.SetBuffer(0, e.Buffer.Length);
this._socket.ReceiveAsync(e);
}
else
{
Close();
}
}
public void SendMsg(string msg)
{
if (_socket == null || !_socket.Connected)
return;
var buffer = Encoding.UTF8.GetBytes(msg);
var args = new SocketAsyncEventArgs();
args.SetBuffer(buffer, 0, buffer.Length);
args.Completed += (sender, eventArgs) =>
{
if (args.SocketError != SocketError.Success)
{
Debug.LogError("消息发送失败!" + args.SocketError);
Close();
}
};
_socket.SendAsync(args);
}
public void Close()
{
if (_socket != null)
{
_socket.Shutdown(SocketShutdown.Both);
_socket.Disconnect(false);
_socket.Close();
_socket = null;
}
}
private void OnDestroy()
{
Close();
}
}