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 = 1024) { 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") + " " + data); using (FileStream fs = log.OpenWrite()) { StreamWriter w = new StreamWriter(fs); w.BaseStream.Seek(0, SeekOrigin.End); w.Write("Send:[{0}] {1} ", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), data); w.Flush(); w.Close(); } } state.workSocket.BeginSend(encode.GetBytes(data), 0, 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) <= 0) 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, 0, 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 = 0; try { //调用这个函数来结束本次接收并返回接收到的数据长度 readCount = state.workSocket.EndReceive(ar); } catch (Exception ex) { return; } try { if (readCount > 0) { byte[] bytes = new byte[readCount]; Array.Copy(state.buffer, 0, bytes, 0, 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") + " " + encode.GetString(bytes)); using (FileStream fs = log.OpenWrite()) { StreamWriter w = new StreamWriter(fs); w.BaseStream.Seek(0, SeekOrigin.End); w.Write("Receive:[{0}] {1} ", 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, 0, 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(3000); 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 > 0) { 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 = 256; /// <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 + " ")); scrollViewer1.ScrollToEnd(); })); }