异步Socket 客户端部分

时间:2021-08-04 19:25:31
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Windows;
using System.IO; namespace IntelliWMS
{
/// <summary>
/// 客户端Socket
/// </summary>
public class ClientSocket
{
#region MyRegion
private StateObject state;
private string host;
private int port;
private int bufferSize; private Thread GuardThread; //守护线程
private AutoResetEvent m_GuardEvent = new AutoResetEvent(false); //守护通知事件
public AutoResetEvent m_ReciveEvent = new AutoResetEvent(false); //接收通知事件 public delegate void Updatedata(string result);
public Updatedata update; public delegate void Updatelog(string log);
public Updatelog uplog; public Queue<byte[]> qBytes = new Queue<byte[]>(); private static Encoding encode = Encoding.UTF8; FileInfo log = new FileInfo("Log.txt"); /// <summary>
/// 类构造函数
/// </summary>
/// <param name="host">ip地址</param>
/// <param name="port">端口</param>
/// <param name="bufferSize"></param>
public ClientSocket(string host, int port, int bufferSize = )
{
this.host = host;
this.port = port;
this.bufferSize = bufferSize; state = new StateObject();
state.workSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
state.buffer = new byte[bufferSize];
} public bool Start(bool startGuardThread)
{
if (state.Connected)
return true; try
{
state.workSocket.BeginConnect(host, port, new AsyncCallback(ConnectCallBack), state);
if (startGuardThread)
{
GuardThread = new Thread(GuardMethod);
GuardThread.IsBackground = true;
GuardThread.Start();
}
return true;
}
catch (Exception ex)
{
return false;
}
} public bool Stop(bool killGuarThread)
{
CloseSocket(state);
if (killGuarThread)
{
try
{
GuardThread.Abort();
}
catch (Exception ex)
{ }
}
return true;
} /// <summary>
/// 发送
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public bool Send(string data)
{
try
{
if (uplog != null)
{
uplog("[Send] " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "\n" + data);
using (FileStream fs = log.OpenWrite())
{
StreamWriter w = new StreamWriter(fs);
w.BaseStream.Seek(, SeekOrigin.End);
w.Write("Send:[{0}] {1}\r\n", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), data);
w.Flush();
w.Close();
}
}
state.workSocket.BeginSend(encode.GetBytes(data), , encode.GetBytes(data).Length, SocketFlags.None, new AsyncCallback(SendCallBack), (object)state);
}
catch (Exception ex)
{
//m_GuardEvent.Set();
return false;
}
return true;
} /// <summary>
/// 发送回调
/// </summary>
/// <param name="ar"></param>
private void SendCallBack(IAsyncResult ar)
{
StateObject state = ar.AsyncState as StateObject;
try
{
if (state.workSocket != null && state.workSocket.Connected && state.workSocket.EndSend(ar) <= )
CloseSocket(state);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
} /// <summary>
/// 连接回调
/// </summary>
/// <param name="ar"></param>
private void ConnectCallBack(IAsyncResult ar)
{
try
{
StateObject state = ar.AsyncState as StateObject;
if (state.workSocket.Connected) //链接成功开始接收数据
{
state.workSocket.BeginReceive(state.buffer, , state.buffer.Length, SocketFlags.None, new AsyncCallback(RecvCallBack), state);
state.Connected = true;
}
state.workSocket.EndConnect(ar);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
} /// <summary>
/// 接收回调
/// </summary>
/// <param name="ar"></param>
private void RecvCallBack(IAsyncResult ar)
{
StateObject state = ar.AsyncState as StateObject;
if (!state.Connected)
{
state.workSocket = null;
return;
}
int readCount = ; try
{
//调用这个函数来结束本次接收并返回接收到的数据长度
readCount = state.workSocket.EndReceive(ar);
}
catch (Exception ex)
{
return;
} try
{
if (readCount > )
{
byte[] bytes = new byte[readCount];
Array.Copy(state.buffer, , bytes, , readCount);
qBytes.Enqueue(bytes);
m_ReciveEvent.Set();
if (update != null)
{
update(encode.GetString(bytes));
uplog("[Receive] " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "\n" + encode.GetString(bytes)); using (FileStream fs = log.OpenWrite())
{
StreamWriter w = new StreamWriter(fs);
w.BaseStream.Seek(, SeekOrigin.End);
w.Write("Receive:[{0}] {1}\r\n", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), encode.GetString(bytes));
w.Flush();
w.Close();
} }
//String2JsonObject(encode.GetString(bytes));
if (state.Connected)
state.workSocket.BeginReceive(state.buffer, , state.buffer.Length, SocketFlags.None, new AsyncCallback(RecvCallBack), state);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message); CloseSocket(state);
}
} /// <summary>
/// 关闭连接
/// </summary>
/// <param name="state"></param>
private void CloseSocket(StateObject state)
{
state.Connected = false; try
{
if (state.workSocket != null)
state.workSocket.Close();
state.workSocket = null;
}
catch (Exception ex)
{ }
} /// <summary>
/// 守护线程
/// </summary>
private void GuardMethod()
{
while (true)
{
Thread.Sleep();
if (state.workSocket == null || state.Connected == false || state.workSocket.Connected == false)
{
state.workSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Start(false);
}
}
} /// <summary>
/// 提供拆包处理
/// </summary>
/// <returns></returns>
public byte[] Revice()
{
byte[] buffer = null;
if (qBytes.Count > )
{
try
{
buffer = qBytes.Dequeue();
}
catch { }
}
return buffer;
} private void String2JsonObject(string json)
{ } #endregion
} #region 构造容器State
/// <summary>
/// 构造容器State
/// </summary>
internal class StateObject
{
/// <summary>
/// Client socket.
/// </summary>
public Socket workSocket = null; /// <summary>
/// Size of receive buffer.
/// </summary>
public const int BufferSize = ; /// <summary>
/// Receive buffer.
/// </summary>
public byte[] buffer = new byte[BufferSize]; /// <summary>
/// Received data string.
/// </summary>
public StringBuilder sb = new StringBuilder(); public bool Connected = false;
}
#endregion
}

以上代码是soket定义

=========================================================================================================

主窗体调用

            string ServerIP = "192.168.0.1";
int ServerPort = 4031; client = new ClientSocket(ServerIP, ServerPort);
client.Start(true);
client.update += Resultdata;  //委托接收Result
client.uplog += updateLog;   //委托显示Send和Result的数据

Resultdata

/// <summary>
/// 服务器Callback
/// </summary>
/// <param name="result">数据</param>
public void Resultdata(string result)
{
//to do
}

在主窗体显示Send和Result的数据

         public void updateLog(string logdata)
{
this.Dispatcher.Invoke(new Action(delegate
{
Log.Inlines.Add(new Run(logdata + "\n"));
scrollViewer1.ScrollToEnd();
}));
}