您好,登錄后才能下訂單哦!
小編給大家分享一下C#如何實現基于Socket套接字的網絡通信封裝,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
之所以要進行Socket套接字通信庫封裝,主要是直接使用套接字進行網絡通信編程相對復雜,特別對于初學者而言。實際上微軟從.net 2.0開始已經提供了TCP、UDP通信高級封裝類如下:
TcpListener
TcpClient
UdpClient
微軟從.net 4.0開始提供基于Task任務的異步通信接口。而直接使用socket封裝庫,很多socket本身的細節沒辦法自行控制,本文目就是提供一種socket的封裝供參考。文中展示部分封裝了TCP通信庫,UDP封裝也可觸類旁通:
CusTcpListener
CusTcpClient
TCP服務端封裝了服務端本地綁定、監聽、接受客戶端連接,并提供了網絡數據流的接口。完整代碼:
public class CusTcpListener { private IPEndPoint mServerSocketEndPoint; private Socket mServerSocket; private bool isActive; public Socket Server { get { return this.mServerSocket; } } protected bool Active { get { return this.isActive; } } public EndPoint LocalEndpoint { get { if (!this.isActive) { return this.mServerSocketEndPoint; } return this.mServerSocket.LocalEndPoint; } } public NetworkStream DataStream { get { NetworkStream networkStream = null; if (this.Server.Connected) { networkStream = new NetworkStream(this.Server, true); } return networkStream; } } public CusTcpListener(IPEndPoint localEP) { this.mServerSocketEndPoint = localEP; this.mServerSocket = new Socket(this.mServerSocketEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); } public CusTcpListener(string localaddr, int port) { if (localaddr == null) { throw new ArgumentNullException("localaddr"); } this.mServerSocketEndPoint = new IPEndPoint(IPAddress.Parse(localaddr), port); this.mServerSocket = new Socket(this.mServerSocketEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); } public CusTcpListener(int port) { this.mServerSocketEndPoint = new IPEndPoint(IPAddress.Any, port); this.mServerSocket = new Socket(this.mServerSocketEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); } public void Start() { this.Start(int.MaxValue); } /// <summary> /// 開始服務器監聽 /// </summary> /// <param name="backlog">同時等待連接的最大個數(半連接隊列個數限制)</param> public void Start(int backlog) { if (backlog > int.MaxValue || backlog < 0) { throw new ArgumentOutOfRangeException("backlog"); } if (this.mServerSocket == null) { throw new NullReferenceException("套接字為空"); } this.mServerSocket.Bind(this.mServerSocketEndPoint); this.mServerSocket.Listen(backlog); this.isActive = true; } public void Stop() { if (this.mServerSocket != null) { this.mServerSocket.Close(); this.mServerSocket = null; } this.isActive = false; this.mServerSocket = new Socket(this.mServerSocketEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); } public Socket AcceptSocket() { Socket socket = this.mServerSocket.Accept(); return socket; } public CusTcpClient AcceptTcpClient() { CusTcpClient tcpClient = new CusTcpClient(this.mServerSocket.Accept()); return tcpClient; } }
TCP客戶端封裝了客戶端本地綁定、連接服務器,并提供了網絡數據流的接口。完整代碼:
public class CusTcpClient : IDisposable { public Socket Client { get; set; } protected bool Active { get; set; } public IPEndPoint ClientSocketEndPoint { get; set; } public bool IsConnected { get { return this.Client.Connected; } } public NetworkStream DataStream { get { NetworkStream networkStream = null; if (this.Client.Connected) { networkStream = new NetworkStream(this.Client, true); } return networkStream; } } public CusTcpClient(IPEndPoint localEP) { if (localEP == null) { throw new ArgumentNullException("localEP"); } this.Client = new Socket(localEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); this.Active = false; this.Client.Bind(localEP); this.ClientSocketEndPoint = localEP; } public CusTcpClient(string localaddr, int port) { if (localaddr == null) { throw new ArgumentNullException("localaddr"); } IPEndPoint localEP = new IPEndPoint(IPAddress.Parse(localaddr), port); this.Client = new Socket(localEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); this.Active = false; this.Client.Bind(localEP); this.ClientSocketEndPoint = localEP; } internal CusTcpClient(Socket acceptedSocket) { this.Client = acceptedSocket; this.Active = true; this.ClientSocketEndPoint = (IPEndPoint)this.Client.LocalEndPoint; } public void Connect(string address, int port) { if (address == null) { throw new ArgumentNullException("address"); } IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(address), port); this.Connect(remoteEP); } public void Connect(IPEndPoint remoteEP) { if (remoteEP == null) { throw new ArgumentNullException("remoteEP"); } this.Client.Connect(remoteEP); this.Active = true; } public void Close() { this.Dispose(true); } protected virtual void Dispose(bool disposing) { if (disposing) { IDisposable dataStream = this.DataStream; if (dataStream != null) { dataStream.Dispose(); } else { Socket client = this.Client; if (client != null) { client.Close(); this.Client = null; } } GC.SuppressFinalize(this); } } public void Dispose() { this.Dispose(true); } }
控制臺程序試驗,服務端程序:
class Program { static void Main(string[] args) { Thread listenerThread = new Thread(ListenerClientConnection); listenerThread.IsBackground = true; listenerThread.Start(); Console.ReadKey(); } private static void ListenerClientConnection() { CusTcpListener tcpListener = new CusTcpListener("127.0.0.1", 5100); tcpListener.Start(); Console.WriteLine("等待客戶端連接……"); while (true) { CusTcpClient tcpClient = tcpListener.AcceptTcpClient(); Console.WriteLine("客戶端接入,ip={0} port={1}", tcpClient.ClientSocketEndPoint.Address, tcpClient.ClientSocketEndPoint.Port); Thread thread = new Thread(DataHandleProcess); thread.IsBackground = true; thread.Start(tcpClient); } } private static void DataHandleProcess(object obj) { CusTcpClient tcpClient = (CusTcpClient)obj; StreamReader streamReader = new StreamReader(tcpClient.DataStream, Encoding.Default); Console.WriteLine("等待客戶端輸入:"); while (true) { try { string receStr = streamReader.ReadLine(); Console.WriteLine(receStr); } catch (Exception) { Console.WriteLine("斷開連接"); break; } Thread.Sleep(5); } } }
客戶端程序:
class Program { static void Main(string[] args) { Thread listenerThread = new Thread(UserProcess); listenerThread.IsBackground = true; listenerThread.Start(); Console.ReadKey(); } private static void UserProcess() { Console.WriteLine("連接服務器"); CusTcpClient tcpClient = new CusTcpClient("127.0.0.1", 5080); tcpClient.Connect("127.0.0.1", 5100); Console.WriteLine("開始和服務器通信"); StreamWriter sw = new StreamWriter(tcpClient.DataStream, Encoding.Default); sw.AutoFlush = true; while (true) { for (int i = 0; i < 10; i++) { string str = string.Format("第{0}次,內容:{1}", i, "測試通信"); Console.WriteLine("發送數據:{0}", str); sw.WriteLine(str); } break; } } }
通信成功:
通過本次封裝演示可實現基于Socket的通信庫封裝,目的就是使用Socket通信庫讓應用開發人員在進行網絡通訊編程時無需關心底層通訊機制,而只關心應用層的開發,讓開發變得更簡潔。當然UDP封裝類似,可自行設計。當然本文只是一種示例,實際使用可使用.net自帶封裝庫或自定義封裝。
以上是“C#如何實現基于Socket套接字的網絡通信封裝”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。