网络通信协议的区别.NET TCP、UDP、Socket、WebSocket-CSDN博客 (2024)

原文链接:https://www.cnblogs.com/kybs0/p/18312434

做.NET应用开发肯定会用到网络通信,而进程间通信是客户端开发使用频率较高的场景。

进程间通信方式主要有命名管道、消息队列、共享内存、Socket通信,个人使用最多的是Sokcet相关。

而Socket也有很多使用方式,Socket、WebSocket、TcpClient、UdpClient,是不是很多?HttpClient与TcpClient、WebSocket之间有什么关系?这里我们分别介绍下这些通信及使用方式

Socket

Socket是传输通信协议么?No,Socket是一种传输层和应用层之间、用于实现网络通信的编程接口。Socket可以使用各种协议如TCP、UDP协议实现进程通信,TCP/UDP才是传输通信协议

Socket位于传输层与应用层之间,接口在System.Net.Sockets命名空间下。下面是Socket以TCP通信的DEMO:

 //创建一个 Socket 实例 Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //连接到服务器 clientSocket.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8000)); //发送数据 string message = "Hello, Server!"; byte\[\] data = Encoding.ASCII.GetBytes(message); clientSocket.Send(data); //接收数据 byte\[\] buffer = new byte\[1024\]; int bytesRead = clientSocket.Receive(buffer); Debug.WriteLine(Encoding.ASCII.GetString(buffer, 0, bytesRead)); clientSocket.Close(); 

TcpClient/UdpClient

TCP/UDP均是位于传输层的通信协议,所以Socket的使用也是位于传输层的通信操作

TCP是面向连接,提供可靠、顺序的数据流传输。用于一对一的通信,即一个TCP连接只能有一个发送方和一个接收方。详细连接方式是,先通过三次握手建立连接、然后传输数据,传输数据完再通过4次挥手关闭连接。所以适用于需要数据完整性和可靠传输的场景

而UDP则是无连接的,不需要建立和维护连接状态,不提供确认机制,也不重传丢失的数据报,但也因此传输实时性高,适合低延时、数据量小、广播场景

基于Socket抽象编程接口,TCP、UDP构建更高级别抽象网络编程TcpClient、UdpClient,它们用于简化TCP网络编程中的常见任务

TcpClient、UdpClient是 .NET 提供的用于方便管理TCP和UDP网络通信的类,下面是对应的Demo

Tcp服务端:

 1 using System; 2 using System.Net; 3 using System.Net.Sockets; 4 using System.Text; 5 6 class TcpServerExample 7 { 8 public static void Main() 9 {10 TcpListener listener = new TcpListener(“127.0.0.1", 8000);11 listener.Start();12 Console.WriteLine("Server is listening on port 8000...");13 14 TcpClient client = listener.AcceptTcpClient();15 NetworkStream stream = client.GetStream();16 17 byte\[\] data = new byte\[1024\];18 int bytesRead = stream.Read(data, 0, data.Length);19 Console.WriteLine("Received: " + Encoding.ASCII.GetString(data, 0, bytesRead));20 21 byte\[\] response = Encoding.ASCII.GetBytes("Hello, Client!");22 stream.Write(response, 0, response.Length);23 24 stream.Close();25 client.Close();26 listener.Stop();27 }28 }

TCP客户端:

 1 using System; 2 using System.Net.Sockets; 3 using System.Text; 4 5 class TcpClientExample 6 { 7 public static void Main() 8 { 9 TcpClient client = new TcpClient("127.0.0.1", 8000);10 NetworkStream stream = client.GetStream();11 12 byte\[\] message = Encoding.ASCII.GetBytes("Hello, Server!");13 stream.Write(message, 0, message.Length);14 15 byte\[\] data = new byte\[1024\];16 int bytesRead = stream.Read(data, 0, data.Length);17 Debug.WriteLine("Received: " + Encoding.ASCII.GetString(data, 0, bytesRead));18 19 stream.Close();20 client.Close();21 }22 }

Udp服务端:

 1 using System; 2 using System.Net; 3 using System.Net.Sockets; 4 using System.Text; 5 6 class UdpServerExample 7 { 8 public static void Main() 9 {10 UdpClient udpServer = new UdpClient(8000);11 IPEndPoint remoteEP = new IPEndPoint(”127.0.0.1“, 0);12 13 Console.WriteLine("Server is listening on port 8000...");14 15 byte\[\] data = udpServer.Receive(ref remoteEP);16 Console.WriteLine("Received: " + Encoding.ASCII.GetString(data));17 18 byte\[\] response = Encoding.ASCII.GetBytes("Hello, Client!");19 udpServer.Send(response, response.Length, remoteEP);20 21 udpServer.Close();22 }23 }

Udp客户端:

 1 using System; 2 using System.Net; 3 using System.Net.Sockets; 4 using System.Text; 5 6 class UdpClientExample 7 { 8 public static void Main() 9 {10 UdpClient udpClient = new UdpClient();11 IPEndPoint remoteEP = new IPEndPoint(”127.0.0.1", 8000);12 13 byte\[\] message = Encoding.ASCII.GetBytes("Hello, Server!");14 udpClient.Send(message, message.Length, remoteEP);15 16 byte\[\] data = udpClient.Receive(ref remoteEP);17 Console.WriteLine("Received: " + Encoding.ASCII.GetString(data));18 19 udpClient.Close();20 }21 }

上面是基本的网络通信DEMO,TcpClient用于基于连接、可靠的TCP通信,适用于需要数据完整性和可靠传输的场景。Udp用于无连接、不保证传输的UDP通信,适用于对实时性要求高、允许少量数据丢失的场景(如视频流)。会议场景下的传屏软件适合用这个协议,传屏发送端固定帧率一直推送,网络丢失几帧问题不大,重要的是延时低了很多。

TcpClient、UdpClient是位于传输层的通信类,分别实现了基于TCP和UDP协议的通信功能。

HttpClient

讲完传输层的网络通信类,就要说下应用层的HttpClient,这是专门用于HTTP协议的通信

Http与TCP/UDP均是网络通信协议,TCP、UDP位于传输层,HTTP传于应用层,而且HTTP是基于TCP面向连接的,它是客户端单向发起的半双工协议。HTTP1.1之后引入持久连接,允许一个TCP连接进行多次请求/响应传输。HTTP层相比TCP它关注请求、响应的内容

HttpClient是Http协议的通信类,提供了封装好的、高级的HTTP功能(如发起GET, POST请求,处理响应等)。

HttpClient可以用于Web接口如Restful API的调用,我这边Windows应用的WebApi基础组件库就是用HttpClient实现的。

HttpClient类,在System.Net.Http.HttpClient命名空间下,HttpClient的内部实现是基于Socket的。也就是说,HttpClient底层使用Socket接口来建立连接并传输数据,但它隐藏了这些细节,为开发者提供了一个更简洁的API。

下面是我基于HttpClient实现的Web服务各类操作入口代码,可以简单浏览下:

 1 /// <summary> 2 /// 请求/推送数据 3 /// </summary> 4 /// <typeparam name="TResponse"></typeparam> 5 /// <param name="request"></param> 6 /// <returns></returns> 7 public async Task<TResponse> RequestAsync<TResponse>(HttpRequest request) where TResponse : HttpResponse, new() 8 { 9 var requestUrl = request.GetRequestUrl();10 try11 {12 using var client = CreateHttpClient(request);13 var requestMethod = request.GetRequestMethod();14 switch (requestMethod)15 {16 case RequestMethod.Get:17 {18 using var response = await client.GetAsync(requestUrl);19 return await response.GetTResponseAsync<TResponse>();20 }21 case RequestMethod.Post:22 {23 using var httpContent = request.GetHttpContent();24 using var response = await client.PostAsync(requestUrl, httpContent);25 return await response.GetTResponseAsync<TResponse>();26 }27 case RequestMethod.Put:28 {29 using var httpContent = request.GetHttpContent();30 using var response = await client.PutAsync(requestUrl, httpContent);31 return await response.GetTResponseAsync<TResponse>();32 }33 case RequestMethod.Delete:34 {35 using var response = await client.DeleteAsync(requestUrl);36 return await response.GetTResponseAsync<TResponse>();37 }38 case RequestMethod.PostForm:39 {40 using var requestMessage = new HttpRequestMessage(HttpMethod.Post, requestUrl);41 using var httpContent = request.GetHttpContent();42 requestMessage.Content = httpContent;43 using var response = await client.SendAsync(requestMessage);44 return await response.GetTResponseAsync<TResponse>();45 }46 }47 return new TResponse() { Message = $"不支持的请求类型:{requestMethod}" };48 }49 catch (ArgumentNullException e)50 {51 return new TResponse() { Code = NetErrorCodes.ParameterError, Message = e.Message, JsonData = e.StackTrace };52 }53 catch (TimeoutException e)54 {55 return new TResponse() { Code = NetErrorCodes.TimeOut, Message = e.Message, JsonData = e.StackTrace };56 }57 catch (Exception e)58 {59 return new TResponse() { Message = e.Message, JsonData = e.StackTrace };60 }61 }

HttpClient封装后的网络基础组件调用方式,也比较简单。

添加接口请求说明,参数及请求参数均统一在一个类文件里定义好:

 1 /// <summary> 2 /// 内网穿透注册接口 3 /// </summary> 4 \[Request("http://frp.supporter.ws.h3c.com/user/register",RequestMethod.Post)\] 5 \[DataContract\] 6 internal class RegisterFrpRequest : HttpRequest 7 { 8 public RegisterFrpRequest(string sn, string appName) 9 {10 Sn = sn;11 SeverNames = new List<RequestServiceName>()12 {13 new RequestServiceName(appName,"http")14 };15 }16 \[DataMember(Name = "sn")\]17 public string Sn { get; set; }18 19 \[DataMember(Name = "localServerNames")\]20 public List<RequestServiceName> SeverNames { get; set; }21 }

再定义请求结果返回数据,基类HttpResponse内有定义基本参数,状态Success、状态码Code、返回描述信息Message:

 1 \[DataContract\] 2 class RegisterFrpResponse : HttpResponse 3 { 4 5 \[DataMember(Name = "correlationId")\] 6 public string CorrelationId { get; set; } 7 8 \[DataMember(Name = "data")\] 9 public FrpRegisterData Data { get; set; }10 11 /// <summary>12 /// 是否成功13 /// </summary>14 public bool IsSuccess => Success && Code == 200000 && Data != null;15 }

然后,业务层可以进行简洁、高效率的调用:

var netClient = new NetHttpClient();

var response = await netClient.RequestAsync<RegisterFrpResponse>(new RegisterFrpRequest(sn, appName));

如果仅仅只是Data数据,可以只定义数据类型,然后使用泛型HttpResponse作为返回数据。

var response1 = await netClient.RequestAsync<HttpResponse<VersionInfo>>(new AppVersionRequest(appId));

WebSocket

WebSocket也是一个应用层通信,不同于可以实现俩类协议TCP/UDP的Socket,WebSocket是以HTTP/HTTPS连接、以TCP传输数据。

一旦握手成功,客户端和服务器之间可以进行双向数据传输,可以传输字节数据也可以传输文本内容。

  • 持久连接:WebSocket 是持久化连接,除非主动关闭,否则在整个会话期间连接保持开放。

  • 全双工通信:客户端和服务器可以随时发送数据,通信不再是单向的。使用System.Net.WebSockets.ClientWebSocket类来实现WebSocket通信,通过减少 HTTP 请求/响应的开销、延时较低。

WebSocketHttpClient呢,都用于应用层的网络通信,但它们的用途和通信协议是不同的。

  • HttpClient使用 HTTP 协议,WebSocket使用WebSocket协议,该协议在初始连接时通过 HTTP/HTTPS握手,然后转换为基于TCP通信的WebSocket协议。所以虽然都有使用HTTP协议,但WebSocket后续就切换至基于TCP的全双工通信了

  • HttpClient基于请求/响应模式,每次通信由客户端向服务器发起请求。WebSocket提供全双工通信,客户端和服务器都可以主动发送数据。

  • HttpClient主要用于访问 RESTful API、下载文件或者发送HTTP请求。WebSocket主要用于实现低延迟的实时通信,如进程间通信、局域网通信等。

我团队Windows应用所使用的进程间通信,就是基于WebSocketSharp封装的。WebSocketSharp是一个功能全面、易于使用的第三方 WebSocket 库 GitHub - sta/websocket-sharp

至于为啥不直接使用ClientWebSocket。。。是因为当时团队还未切换.NET,使用的是.NETFramework。

后面团队使用的局域网通信基础组件就是用ClientWebSocket了。

下面是我封装的部分WebSocket通信代码,事件发送(广播)、以及监听其它客户端发送过来的事件消息:

 1 /// <summary> 2 /// 发送消息 3 /// </summary> 4 /// <typeparam name="TInput">发送参数类型</typeparam> 5 /// <param name="client">目标客户端</param> 6 /// <param name="innerEvent">事件名</param> 7 /// <param name="data">发送参数</param> 8 /// <returns></returns> 9 public async Task<ClientResponse> SendAsync<TInput>(string client, InnerEventItem innerEvent, TInput data)10 {11 var message = new ChannelSendingMessage(client, new ClientEvent(innerEvent.EventName, innerEvent.EventId, true), \_sourceClient);12 message.SetData<TInput>(data);13 return await SendMessageAsync(ChannelMessageType.ClientCommunication, message);14 }15 16 /// <summary>17 /// 订阅消息18 /// </summary>19 /// <param name="client">目标客户端</param>20 /// <param name="innerEvent">事件名称</param>21 /// <param name="func">委托</param>22 public ClientSubscribedEvent SubscribeFunc(string client, InnerEventItem innerEvent, Func<ClientResponse, object\> func)23 {24 var eventName = innerEvent?.EventName;25 if (string.IsNullOrEmpty(eventName) || func == null)26 {27 throw new ArgumentNullException($"{nameof(eventName)}或{nameof(func)},参数不能为空!");28 }29 30 var subscribedEvent = new ClientSubscribedEvent(client, innerEvent, func);31 SubscribeEvent(subscribedEvent);32 return subscribedEvent;33 }34 /// <summary>35 /// 订阅消息36 /// </summary>37 /// <param name="client">目标客户端</param>38 /// <param name="innerEvent">事件名称</param>39 /// <param name="func">委托</param>40 public ClientSubscribedEvent SubscribeFuncTask(string client, InnerEventItem innerEvent, Func<ClientResponse, Task<object\>> func)41 {42 var eventName = innerEvent?.EventName;43 if (string.IsNullOrEmpty(eventName) || func == null)44 {45 throw new ArgumentNullException($"{nameof(eventName)}或{nameof(func)},参数不能为空!");46 }47 48 var subscribedEvent = new ClientSubscribedEvent(client, innerEvent, func);49 SubscribeEvent(subscribedEvent);50 return subscribedEvent;51 }52 53 /// <summary>54 /// 订阅消息55 /// </summary>56 /// <param name="client">目标客户端</param>57 /// <param name="innerEvent">事件名称</param>58 /// <param name="action">委托</param>59 public ClientSubscribedEvent Subscribe(string client, InnerEventItem innerEvent, Action<ClientResponse> action)60 {61 var eventName = innerEvent?.EventName;62 if (string.IsNullOrEmpty(eventName) || action == null)63 {64 throw new ArgumentNullException($"{nameof(eventName)}或{nameof(action)},参数不能为空!");65 }66 67 var subscribedEvent = new ClientSubscribedEvent(client, innerEvent, action);68 SubscribeEvent(subscribedEvent);69 return subscribedEvent;70 }
网络通信协议的区别.NET TCP、UDP、Socket、WebSocket-CSDN博客 (2024)
Top Articles
Sacramento Craigslist Cars And Trucks - By Owner
Recraft Lariat
Maxtrack Live
Uhauldealer.com Login Page
Walgreens Pharmqcy
Obor Guide Osrs
Wizard Build Season 28
Team 1 Elite Club Invite
Google Jobs Denver
Phenix Food Locker Weekly Ad
Computer Repair Tryon North Carolina
Optimal Perks Rs3
World Cup Soccer Wiki
Audrey Boustani Age
Hmr Properties
Lax Arrivals Volaris
7440 Dean Martin Dr Suite 204 Directions
10-Day Weather Forecast for Santa Cruz, CA - The Weather Channel | weather.com
Northeastern Nupath
Csi Tv Series Wiki
Kp Nurse Scholars
Army Oubs
Accident On 215
Shadbase Get Out Of Jail
Directions To Nearest T Mobile Store
Kentuky Fried Chicken Near Me
Apparent assassination attempt | Suspect never had Trump in sight, did not get off shot: Officials
Cardaras Funeral Homes
Nottingham Forest News Now
What Is The Lineup For Nascar Race Today
Citibank Branch Locations In Orlando Florida
Colin Donnell Lpsg
Nextdoor Myvidster
Ixlggusd
Royal Caribbean Luggage Tags Pending
Indiana Wesleyan Transcripts
Jennifer Reimold Ex Husband Scott Porter
Tirage Rapid Georgia
Planet Fitness Santa Clarita Photos
Pp503063
Kelley Blue Book Recalls
Felix Mallard Lpsg
Noaa Duluth Mn
Craigslist Com Panama City Fl
Tunica Inmate Roster Release
Shoecarnival Com Careers
Jamesbonchai
Valls family wants to build a hotel near Versailles Restaurant
Gander Mountain Mastercard Login
Tìm x , y , z :a, \(\frac{x+z+1}{x}=\frac{z+x+2}{y}=\frac{x+y-3}{z}=\)\(\frac{1}{x+y+z}\)b, 10x = 6y và \(2x^2\)\(-\) \(...
Where and How to Watch Sound of Freedom | Angel Studios
Powah: Automating the Energizing Orb - EnigmaticaModpacks/Enigmatica6 GitHub Wiki
Latest Posts
Article information

Author: Carmelo Roob

Last Updated:

Views: 6432

Rating: 4.4 / 5 (65 voted)

Reviews: 80% of readers found this page helpful

Author information

Name: Carmelo Roob

Birthday: 1995-01-09

Address: Apt. 915 481 Sipes Cliff, New Gonzalobury, CO 80176

Phone: +6773780339780

Job: Sales Executive

Hobby: Gaming, Jogging, Rugby, Video gaming, Handball, Ice skating, Web surfing

Introduction: My name is Carmelo Roob, I am a modern, handsome, delightful, comfortable, attractive, vast, good person who loves writing and wants to share my knowledge and understanding with you.