异步服务器端
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
namespace SocketTool
{
public enum ClientStatus
{
/// <summary>
/// 客户端链接
/// </summary>
connnected,
/// <summary>
/// 客户端正常
/// </summary>
normal,
/// <summary>
/// 客户端关闭
/// </summary>
disconnected
}
//保存客户端连接信息
public class ConnectionInfo
{
public Socket Socket;/// 客户端链接实例
public byte[] RveBuffer; /// 接收客户端数据缓冲区
public byte[] SendBuffer; /// 发送客户端数据缓冲区
public string Data;///客户端发的数据
public ClientStatus ClientStatus; /// 客户端状态
}
/// <summary>
/// 自定义事件参数
/// </summary>
public class TcpMsgEventArgs : EventArgs
{
public string Msg { get; set; }
public ConnectionInfo clienInfo { get; set; }
public TcpMsgEventArgs(ConnectionInfo info, string text)
{
clienInfo = info;
Msg = text;
}
}
class SocketServer
{
private Socket sock;
private int clientNumb = 0;
private byte[] byText;
public List<ConnectionInfo> clientConnections = new List<ConnectionInfo>();
//定义收到客户端消息delegate
public delegate void ReceiveFromClientMsgEventHandler(object sender, TcpMsgEventArgs e);
//用event 关键字声明事件对象
public event ReceiveFromClientMsgEventHandler ReceiveFromClientMsgEvent;
//定义向客户端发送消息delegate
public delegate void SendToClientMsgEventHandler(object sender, TcpMsgEventArgs e);
//用event 关键字声明事件对象
public event SendToClientMsgEventHandler SendToClientMsgEvent;
/// <summary>
/// 服务器监听tcp端口并接收信息
/// </summary>
public bool BeginServer()
{
try
{
string hostname = System.Net.Dns.GetHostName();
System.Net.IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(hostname);//ipEntry.AddressList[0].ToString()
IPAddress myip = IPAddress.Any;
IPEndPoint myserver = new IPEndPoint(myip, 60000);
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Bind(myserver);
sock.Listen(50);
sock.BeginAccept(new AsyncCallback(Accept), null);
}
catch (Exception ex)
{
Debug.Log("" + ex.Message);
return false;
}
return true;
}
/// <summary>
/// 监听客户端
/// </summary>
/// <param name="ar"></param>
private void Accept(IAsyncResult ar)
{
try
{
Socket ClientSocket = sock.EndAccept(ar);
IPEndPoint ep = ClientSocket.RemoteEndPoint as IPEndPoint;
// ClientSocket[clientNumb].BeginReceive(MsgBuffer, 0, MsgBuffer.Length, 0,new AsyncCallback(Accept), ClientSocket[clientNumb]);
Debug.Log(ep.ToString() + "客户端连接成功");
ClientPro(ClientSocket);
clientNumb++;
}
catch (Exception ex)
{
Debug.Log("出错:" + ex.Message);
}
finally
{
sock.BeginAccept(new AsyncCallback(Accept), null);
}
}
/// <summary>
/// 连接客户端后做处理过程启动异步接收
/// </summary>
/// <param name="clientSock"></param>
private void ClientPro(Socket clientSock)
{
IPEndPoint ep = clientSock.RemoteEndPoint as IPEndPoint;
ConnectionInfo ci = new ConnectionInfo();
ci.Socket = clientSock;
ci.RveBuffer = new byte[1024];
lock (clientConnections)
{
clientConnections.Add(ci);
}
///向客户端发送自己的ip和端口,来作为区别的唯一标识
//启动异步接收过程
clientSock.BeginReceive(ci.RveBuffer, 0, ci.RveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), ci);
//客户端首次链接成功后,置客户端状态为"连接成功"
ci.ClientStatus = ClientStatus.normal;
}
/// <summary>
/// 回调函数做数据处理
/// </summary>
/// <param name="result"></param>
private void ReceiveCallback(IAsyncResult result)
{
ConnectionInfo ci = (ConnectionInfo)result.AsyncState;
if (ci == null || ci.Socket == null || ci.Socket.Connected == false)
{
return;
}
try
{
//得到客户端信息
IPEndPoint ep = ci.Socket.RemoteEndPoint as IPEndPoint;
string ip = ep.Address.ToString();
int port = ep.Port;
if (ip == null || ip.Length == 0)
{
ip = "0.0.0.0";
port = 0;
}
int bytesRead = ci.Socket.EndReceive(result);
/*
若接收到的数据为0,则客户端断开链接
*/
if (bytesRead == 0)
{
CloseConnection(ci);
return;
}
byText = new byte[bytesRead];
Array.Copy(ci.RveBuffer, 0, byText, 0, bytesRead);
string s = Encoding.ASCII.GetString(byText);
ci.Data = s;
//触发接收消息事件
if (ReceiveFromClientMsgEvent != null)
{
ReceiveFromClientMsgEvent(this, new TcpMsgEventArgs(ci, s));
}
//读取数据成功后,置当前客户状态为 一般
byte[] data = new byte[1024];
//BeginServerTreatment(ci);
ci.ClientStatus = ClientStatus.normal;
}
catch (SocketException ex)
{
CloseConnection(ci);
Debug.Log("SocketException:" + ex.Message);
}
catch (Exception ex)
{
CloseConnection(ci);
Debug.Log("Exception:" + ex.Message);
}
finally
{
if (ci.Socket.Connected == true)
{
//等待接收数据
ci.Socket.BeginReceive(ci.RveBuffer, 0, ci.RveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), ci);
}
}
}
/// <summary>
/// 关闭当前链接,并从内存中清除相应记录
/// </summary>
/// <param name="ci"></param>
private void CloseConnection(ConnectionInfo ci)
{
try
{
IPEndPoint ep = ci.Socket.RemoteEndPoint as IPEndPoint;
ci.Socket.Close();
Debug.Log("客户端" + ep.Address.ToString() + "已经断开连接");
}
catch (Exception ex)
{
Debug.Log("断开连接异常:" + ex.Message);
}
finally
{
lock (clientConnections)
{
clientConnections.Remove(ci);
}
}
}
/// <summary>
/// 向所有客户端发送 单个客户端状态数据
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public bool ServerSendAll(byte[] data)
{
for (int i = 0; i < clientConnections.Count; i++)
{
IPEndPoint ep = clientConnections[i].Socket.RemoteEndPoint as IPEndPoint;
NetworkStream ns = new NetworkStream(clientConnections[i].Socket);
try
{
ns.Write(data, 0, data.Length);
if (SendToClientMsgEvent != null)
{
SendToClientMsgEvent(this, new TcpMsgEventArgs(clientConnections[i], System.Text.Encoding.ASCII.GetString(data)));
}
}
catch (Exception ex)
{
Debug.Log("所有客户端NS数据流对象写入失败" + ex.Message);
return false;
}
}
return true;
}
/// <summary>
/// 向所有客户端发送状态数据一般状态
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public bool ServerSendAll(string msg)
{
for (int i = 0; i < clientConnections.Count; i++)
{
string serverdata = msg;
byte[] data = new byte[1024];
data = Encoding.Unicode.GetBytes(serverdata);
try
{
for (int j = 0; j < clientConnections.Count; j++)
{
IPEndPoint ep = clientConnections[i].Socket.RemoteEndPoint as IPEndPoint;
NetworkStream ns = new NetworkStream(clientConnections[j].Socket);
ns.Write(data, 0, data.Length);
if (SendToClientMsgEvent != null)
{
SendToClientMsgEvent(this, new TcpMsgEventArgs(clientConnections[i], msg));
}
Thread.Sleep(100);
}
}
catch (Exception ex)
{
Debug.Log("所有客户端NS数据流对象写入失败" + ex.Message);
return false;
}
}
return true;
}
/// <summary>
/// 向单独客户端发送数据
/// </summary>
/// <param name="ci"></param>
/// <param name="data"></param>
/// <returns></returns>
public bool ServerSendOne(ConnectionInfo ci, byte[] data)
{
IPEndPoint ep = ci.Socket.RemoteEndPoint as IPEndPoint;
NetworkStream ns = new NetworkStream(ci.Socket);
try
{
ns.Write(data, 0, data.Length);
if (SendToClientMsgEvent != null)
{
SendToClientMsgEvent(this, new TcpMsgEventArgs(ci, System.Text.Encoding.ASCII.GetString(data)));
}
}
catch (Exception ex)
{
Debug.Log("单独客户端NS数据流对象写入失败" + ex.Message);
return false;
}
return true;
}
}
}
服务器使用方法
SocketServer sckServer = new SocketServer();
sckServer.ReceiveFromClientMsgEvent += SckServer_ReceiveClientMsgEvent;
sckServer.SendToClientMsgEvent += SckServer_SendToClientMsgEvent;
bool bSuc = sckServer.BeginServer();
private void SckServer_SendToClientMsgEvent(object sender, TcpMsgEventArgs e)
{
}
//消息接收事件处理
private void SckServer_ReceiveClientMsgEvent(object sender, TcpMsgEventArgs e)
{
}
异步客户端
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Timers;
namespace MotionDetectorSample.Custom
{
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 256;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
public class SocketClient
{
public bool IsConnect = false;
//定义收到服务器端消息delegate
public delegate void ReceiveFromServerMsgEventHandler(object sender, TcpMsgEventArgs e);
//用event 关键字声明事件对象
public event ReceiveFromServerMsgEventHandler ReceiveFromServerMsgEvent;
// The port number for the remote device.
private const int port = 11000;
// ManualResetEvent instances signal completion.
private ManualResetEvent connectDone = new ManualResetEvent(false);
private ManualResetEvent sendDone = new ManualResetEvent(false);
private ManualResetEvent receiveDone = new ManualResetEvent(false);
// The response from the remote device.
private String response = String.Empty;
private Socket client;
public void StartConnectServer(string newIp, int newPort)
{
// Connect to a remote device.
try
{
IPAddress ipAddress = IPAddress.Parse(newIp);
IPEndPoint remoteEP = new IPEndPoint(ipAddress, newPort);
// Create a TCP/IP socket.
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
IsConnect = false;
}
}
public void Close()
{
try
{
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
IsConnect = false;
}
}
private void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString());
// Signal that the connection has been made.
connectDone.Set();
Receive(client);
IsConnect = true;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
IsConnect = false;
}
}
private void Receive(Socket client)
{
try
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
IsConnect = false;
}
}
private void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
string rec = Encoding.ASCII.GetString(state.buffer, 0, bytesRead);
Console.WriteLine("received:" + rec);
ReceiveFromServerMsgEvent(this, new TcpMsgEventArgs(rec));
IsConnect = true;
// Get the rest of the data.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
else
{
// All the data has arrived; put it in response.
if (state.sb.Length > 1)
{
response = state.sb.ToString();
Console.WriteLine("response:" + response);
}
// Signal that all bytes have been received.
receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public void SendCommand(String data)
{
try
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
IsConnect = true;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
IsConnect = false;
}
}
private void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
//Console.WriteLine("Sent {0} bytes to server.", bytesSent);
// Signal that all bytes have been sent.
sendDone.Set();
IsConnect = true;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
/// <summary>
/// 自定义事件参数
/// </summary>
public class TcpMsgEventArgs : EventArgs
{
public string Msg { get; set; }
public TcpMsgEventArgs(string text)
{
Msg = text;
}
}
}
Custom.SocketClient sckClient = new Custom.SocketClient();
sckClient.ReceiveFromServerMsgEvent += SckClient_ReceiveFromServerMsgEvent;
sckClient.StartConnectServer(RemoteTcpServerIp, RemoteTcpServerPort);
private void SckClient_ReceiveFromServerMsgEvent(object sender, TcpMsgEventArgs e)
{
}
客户端使用