边肖将与大家分享C#如何实现基于Socket套接字的网络通信封装。相信大部分人还不太了解,所以分享这篇文章给大家参考。希望你看完这篇文章后收获多多。让我们一起来发现吧!
摘要
之所以要打包Socket通信库,是因为直接使用Socket进行网络通信编程相对复杂,尤其是初学者。事实上,微软从2000年开始就为TCP和UDP通信提供了高级封装类。net 2.0,如下所示:
服务器
客户端
客户端
微软开始提供基于任务的异步通信接口。net 4.0。但是,直接使用socket包库,socket本身的很多细节是无法自己控制的。本文的目的是提供一个插座包供参考。本文将TCP通信库封装在显示部分,UDP封装也可以绕过这个类比:
CusTcpListener
CusTcpClient
TCP服务端
TCP服务器封装了服务端本地绑定、监听、接受客户端连接,并提供了网络数据流的接口。完整代码:
publicclassCusTcpListener
{
privatependpointmserversocketend point;
privateSocketmServerSocket
privateboolisActive
publicSocketServer
{
get { returnthis.mServerSocket}
}
受保护的工具活动
{
get { returnthis.isActive}
}
publiceendpointlocalendpoint
{
得到
{
if(!this.isActive)
{
returnthis . mserversocketend point;
}
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客户端
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套接字的网络通信封装”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/119729.html