C# Socket系列二 简单的创建 socket 通信
生活随笔
收集整理的這篇文章主要介紹了
C# Socket系列二 简单的创建 socket 通信
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
看了系列一 我們開啟了對socket tcp的監聽狀態,那么這一章我們來講解怎么創建socket的通信代碼
我新建一個類?TSocketBase
public abstract class TSocketBase{//封裝socketinternal Socket _Socket;//回調private AsyncCallback aCallback;//接受數據的緩沖區private byte[] Buffers;//標識是否已經釋放private volatile bool IsDispose;//10K的緩沖區空間private int BufferSize = 10*1024;//收取消息狀態碼private SocketError ReceiveError;//發送消息的狀態碼private SocketError SenderError;//每一次接受到的字節數private int ReceiveSize = 0;//接受空消息次數private byte ZeroCount = 0;public abstract void Receive(byte[] rbuff);public void SetSocket(){this.aCallback = new AsyncCallback(this.ReceiveCallback);this.IsDispose = false;this._Socket.ReceiveBufferSize = this.BufferSize;this._Socket.SendBufferSize = this.BufferSize;this.Buffers = new byte[this.BufferSize];}/// <summary>/// 關閉并釋放資源/// </summary>/// <param name="msg"></param>public void Close(string msg){if (!this.IsDispose){this.IsDispose = true;try{try{this._Socket.Close();}catch{}IDisposable disposable = this._Socket;if (disposable != null){disposable.Dispose();}this.Buffers = null;GC.SuppressFinalize(this);}catch (Exception){}}}/// <summary>/// 遞歸接收消息方法/// </summary>internal void ReceiveAsync(){try{if (!this.IsDispose && this._Socket.Connected){this._Socket.BeginReceive(this.Buffers, 0, this.BufferSize, SocketFlags.None, out SenderError,this.aCallback, this);CheckSocketError(ReceiveError);}}catch (System.Net.Sockets.SocketException){this.Close("鏈接已經被關閉");}catch (System.ObjectDisposedException){this.Close("鏈接已經被關閉");}}/// <summary>/// 接收消息回調函數/// </summary>/// <param name="iar"></param>private void ReceiveCallback(IAsyncResult iar){if (!this.IsDispose){try{//接受消息ReceiveSize = _Socket.EndReceive(iar, out ReceiveError);//檢查狀態碼if (!CheckSocketError(ReceiveError) && SocketError.Success == ReceiveError){//判斷接受的字節數if (ReceiveSize > 0){byte[] rbuff = new byte[ReceiveSize];Array.Copy(this.Buffers, rbuff, ReceiveSize);this.Receive(rbuff);//重置連續收到空字節數ZeroCount = 0;//繼續開始異步接受消息ReceiveAsync();}else{ZeroCount++;if (ZeroCount == 5){this.Close("錯誤鏈接");}}}}catch (System.Net.Sockets.SocketException){this.Close("鏈接已經被關閉");}catch (System.ObjectDisposedException){this.Close("鏈接已經被關閉");}}}/// <summary>/// 錯誤判斷/// </summary>/// <param name="socketError"></param>/// <returns></returns>private bool CheckSocketError(SocketError socketError){switch ((socketError)){case SocketError.SocketError:case SocketError.VersionNotSupported:case SocketError.TryAgain:case SocketError.ProtocolFamilyNotSupported:case SocketError.ConnectionAborted:case SocketError.ConnectionRefused:case SocketError.ConnectionReset:case SocketError.Disconnecting:case SocketError.HostDown:case SocketError.HostNotFound:case SocketError.HostUnreachable:case SocketError.NetworkDown:case SocketError.NetworkReset:case SocketError.NetworkUnreachable:case SocketError.NoData:case SocketError.OperationAborted:case SocketError.Shutdown:case SocketError.SystemNotReady:case SocketError.TooManyOpenSockets:this.Close(socketError.ToString());return true;}return false;}/// <summary>/// 發送消息方法/// </summary>internal int SendMsg(byte[] buffer){int size = 0;try{if (!this.IsDispose){size = this._Socket.Send(buffer, 0, buffer.Length, SocketFlags.None, out SenderError);CheckSocketError(SenderError);}}catch (System.ObjectDisposedException){this.Close("鏈接已經被關閉");}catch (System.Net.Sockets.SocketException){this.Close("鏈接已經被關閉");}buffer = null;return size;}}上面我們事先了socket的異步接受消息,和同步發送消息已經關閉釋放資源代碼
接受消息net底層提供的接受消息的方法有很多,為什么我們要選擇上面所寫的呢?那是為了兼容U3D,silverlight, wpf, wp, wf,等程序可執行,不在重復做相同工作。
現在我們來創建一個實現類?TSocketClient
public class TSocketClient : TSocketBase{/// <summary>/// 是否是服務器端的資源/// </summary>private bool isServer = false;/// <summary>/// 客戶端主動請求服務器/// </summary>/// <param name="ip"></param>/// <param name="port"></param>public TSocketClient(string ip = "127.0.0.1", int port = 9527){isServer = false;this._Socket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);this._Socket.Connect(ip, port);this.SetSocket();this.ReceiveAsync();}/// <summary>/// 這個是服務器收到有效鏈接初始化/// </summary>/// <param name="socket"></param>public TSocketClient(Socket socket){isServer = true;this._Socket = socket;this.SetSocket();this.ReceiveAsync();}/// <summary>/// 收到消息后/// </summary>/// <param name="rbuff"></param>public override void Receive(byte[] rbuff){Console.WriteLine("Receive Msg:" + System.Text.UTF8Encoding.Default.GetString(rbuff));if (isServer){this.SendMsg(System.Text.UTF8Encoding.Default.GetBytes("Holle Client!"));}}}因為是測試示例,所以我把服務器和客戶端實現類寫成了,只是用來不同的構造函數來區分,是客戶端還是服務器的標識
接下來我們測試一下代碼
1 class Program2 {3 static void Main(string[] args)4 {5 TCPListener tcp = new TCPListener();6 TSocketClient client = new TSocketClient();7 client.SendMsg(System.Text.UTF8Encoding.Default.GetBytes("Holle Server!"));8 Console.ReadLine();9 } 10 }運行結果看出,我們連接成功并且發送消息成功。
總結
以上是生活随笔為你收集整理的C# Socket系列二 简单的创建 socket 通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# Socket系列一 简单的创建so
- 下一篇: 串行,并行,并发