C#Socket客户端
C#開發Socket客戶端
我們先新建一個類:SocketClientAsync。
注意點:
1、由于Socket通訊是發送到緩存區內的數據是覆蓋,而不是新的,也就是說如果我們第一次發送的內容是 byte[]{0x11,0x22};而第二次發送的內容是byte[]{0x22}。那么我們的服務端在第二次接受到的數據是byte[]{0x22,0x22}。
所以我們需要在Socket.Send(byte[] mes)方法里面聲明
byte[] buffer = new byte[1024];
for (int i = 0; i < buffer.Length; i++)
?{
? ? ? ? buffer[i] = 0x00;
}
起到的作用就是每次在發送新的內容到服務端的時候,會將所有的舊的內容替換掉;
2、關閉連接之前需要將通知服務端停止發送和接受,也就是
?this.clientSocket.Shutdown(SocketShutdown.Both);
中斷套接字連接:通知服務器端或客戶端停止接收和發送數據。
通知完成之后如果客戶端還連接著再進行自己的連接斷開
if (this.clientSocket.Connected)
?{
? ? ? ? ?this.clientSocket.Close();
}
3、具體類的代碼見下圖,可以直接使用
#region SocketClient客戶端public class SocketClientAsync{#region 聲明變量public string IPAdress;public bool connected = false;public Socket clientSocket;private IPEndPoint hostEndPoint;private int Flag = 0;private AutoResetEvent autoConnectEvent = new AutoResetEvent(false);private SocketAsyncEventArgs lisnterSocketAsyncEventArgs;public delegate void StartListeHandler();public event StartListeHandler StartListen;public delegate void ReceiveMsgHandler(byte[] info, int i);public event ReceiveMsgHandler OnMsgReceived;private List<SocketAsyncEventArgs> s_lst = new List<SocketAsyncEventArgs>();#endregion#region 構造函數/// <summary>/// 構造函數/// </summary>/// <param name="hostName"></param>/// <param name="port"></param>/// <param name="i"></param>public SocketClientAsync(string hostName, int port, int i){Flag = i;IPAdress = hostName;IPAddress[] hostAddresses = Dns.GetHostAddresses(hostName);this.hostEndPoint = new IPEndPoint(hostAddresses[hostAddresses.Length - 1], port);this.clientSocket = new Socket(this.hostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);}#endregion#region 開始連接服務端/// <summary>/// 連接服務端/// </summary>/// <returns></returns>private bool Connect(){using (SocketAsyncEventArgs args = new SocketAsyncEventArgs()){args.UserToken = this.clientSocket;args.RemoteEndPoint = this.hostEndPoint;args.Completed += new EventHandler<SocketAsyncEventArgs>(this.OnConnect);this.clientSocket.ConnectAsync(args);bool flag = autoConnectEvent.WaitOne(5000);if (this.connected){this.lisnterSocketAsyncEventArgs = new SocketAsyncEventArgs();byte[] buffer = new byte[1024];this.lisnterSocketAsyncEventArgs.UserToken = this.clientSocket;this.lisnterSocketAsyncEventArgs.SetBuffer(buffer, 0, buffer.Length);this.lisnterSocketAsyncEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(this.OnReceive);this.StartListen();return true;}return false;}}#endregion#region 判斷有沒有連接上服務端/// <summary>/// 判斷有沒有連接上/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void OnConnect(object sender, SocketAsyncEventArgs e){this.connected = (e.SocketError == SocketError.Success);autoConnectEvent.Set();}#endregion#region 發送數據到服務端/// <summary>/// 發送/// </summary>/// <param name="mes"></param>public void Send(byte[] mes){if (this.connected){EventHandler<SocketAsyncEventArgs> handler = null;//byte[] buffer = Encoding.Default.GetBytes(mes);byte[] buffer = new byte[1024];for (int i = 0; i < buffer.Length; i++){buffer[i] = 0x00;}Array.Copy(mes, 0, buffer, 0, mes.Length);SocketAsyncEventArgs senderSocketAsyncEventArgs = null;lock (s_lst){if (s_lst.Count > 0){senderSocketAsyncEventArgs = s_lst[s_lst.Count - 1];s_lst.RemoveAt(s_lst.Count - 1);}}if (senderSocketAsyncEventArgs == null){senderSocketAsyncEventArgs = new SocketAsyncEventArgs();senderSocketAsyncEventArgs.UserToken = this.clientSocket;senderSocketAsyncEventArgs.RemoteEndPoint = this.clientSocket.RemoteEndPoint;if (handler == null){handler = delegate(object sender, SocketAsyncEventArgs _e){lock (s_lst){s_lst.Add(senderSocketAsyncEventArgs);}};}senderSocketAsyncEventArgs.Completed += handler;}senderSocketAsyncEventArgs.SetBuffer(buffer, 0, buffer.Length);this.clientSocket.SendAsync(senderSocketAsyncEventArgs);}else{this.connected = false;}}#endregion#region 監聽服務端/// <summary>/// 監聽服務端/// </summary>public void Listen(){if (this.connected && this.clientSocket != null){try{(lisnterSocketAsyncEventArgs.UserToken as Socket).ReceiveAsync(lisnterSocketAsyncEventArgs);}catch (Exception){}}}#endregion#region 斷開服務端的連接/// <summary>/// 斷開連接/// </summary>/// <returns></returns>private int Disconnect(){int res = 0;try{this.clientSocket.Shutdown(SocketShutdown.Both);}catch (Exception){}try{this.clientSocket.Close();}catch (Exception){}this.connected = false;return res;}#endregion#region 數據接收/// <summary>/// 數據接受/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void OnReceive(object sender, SocketAsyncEventArgs e){if (e.BytesTransferred == 0){if (clientSocket.Connected){try{this.clientSocket.Shutdown(SocketShutdown.Both);}catch (Exception){}finally{if (this.clientSocket.Connected){this.clientSocket.Close();}}}byte[] info = new Byte[] { 0 };this.OnMsgReceived(info, Flag);}else{byte[] buffer = new byte[e.BytesTransferred];Buffer.BlockCopy(e.Buffer, 0, buffer, 0, e.BytesTransferred);this.OnMsgReceived(buffer, Flag);Listen();}}#endregion#region 建立連接服務端的方法/// <summary>/// 建立連接的方法/// </summary>/// <returns></returns>public bool ConnectServer(){bool flag = false;this.StartListen += new StartListeHandler(SocketClient_StartListen);// this.OnMsgReceived += new ReceiveMsgHandler(SocketClient_OnMsgReceived);flag = this.Connect();if (!flag){return flag;}return true;}#endregion#region 關閉與服務端之間的連接/// <summary>/// 關閉連接的方法/// </summary>/// <returns></returns>public int CloseLinkServer(){return this.Disconnect();}#endregion#region 監聽方法/// <summary>/// 監聽的方法/// </summary>private void SocketClient_StartListen(){this.Listen();}#endregion#region IDispose memberpublic void Dispose(){if (this.clientSocket.Connected){this.clientSocket.Close();}}#endregion#region 析構函數~SocketClientAsync(){try{if (this.clientSocket.Connected){this.clientSocket.Close();}}catch{}finally{}}#endregion}#endregion?
4、然后就是類的調用了
//聲明定義變量private SocketClientAsync ClientLink;//客戶端連接對象private string Client_IP = "127.0.0.1";//服務端IP地址private int Client_Port = 12345;//服務端監聽的端口號private Thread Client_Td;//通訊內部使用線程private bool ClientLinkRes = false;//服務器通訊狀態標志private bool ThreadContinue = true;//線程輪詢標志private bool isOnline = false;//是否在線標志/// <summary>/// 啟動線程/// </summary>private void StartServer(){Client_Td = new Thread(LinkSocketSerFunc);Client_Td.Start();}/// <summary>/// 重連服務端線程/// </summary>private void LinkSocketSerFunc(){object lockobj = new object();int heartBeatCount = 0;ClientLink = new SocketClientAsync(Client_IP, Client_Port, 0);bool NotFirstIn = false;while (ThreadContinue){try{if (!ClientLinkRes){isOnline = false;if (NotFirstIn){ClientLink.CloseLinkServer();ClientLink = new SocketClientAsync(Client_IP, Client_Port, 0);}NotFirstIn = true;ClientLink.OnMsgReceived += new SocketClientAsync.ReceiveMsgHandler(Client_OnMsgReceived);//綁定接受到服務端消息的事件ClientLinkRes = ClientLink.ConnectServer();}else{//此處寫通訊成功的邏輯處理}}catch (Exception ex){ClientLinkRes = false;System.Diagnostics.Debug.WriteLine(ex.ToString());}Thread.Sleep(1000);}}/// <summary>/// 接收消息處理/// </summary>/// <param name="info"></param>/// <param name="num"></param>private void Client_OnMsgReceived(byte[] info, int num){try{ClientHeartBeat = 0;if (info.Length > 0 && info[0] != 0)//BCR連接錯誤NO{//info為接受到服務器傳過來的字節數組,需要進行什么樣的邏輯處理在此書寫便可 }else{ClientLinkRes = false;}}catch (Exception ex){System.Diagnostics.Debug.WriteLine(ex.ToString());}}/// <summary>/// 終止服務/// </summary>public void StopServer(){if (ClientLinkRes){ThreadContinue = false;ClientLink.CloseLinkServer();ClientLink.Dispose();}}以上,基本的Socket客戶端后臺就寫完了,可以直接復制使用,平時都是用這么去寫Socket客戶端,分享出來,以后大家就可以直接使用了,程序員要學會偷懶!!!
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的C#Socket客户端的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里云rds升级mysql8_为更强大而
- 下一篇: input子系统基础之按键1——什么是i