好看简单易做的网站,关于网站设计的书,小程序购物平台,wordpress和emlog本文对代码的讲解基于上一篇博客
快速链接
Socket编程详解#xff08;一#xff09;服务端与客户端的双向对话 小试牛刀1#xff1a;委托声明的关键字和委托方法使用的方法名是不一样的名称 可读性#xff1a;有时#xff0c;委托的名称可能描述了它的用途或它在哪里被…本文对代码的讲解基于上一篇博客
快速链接
Socket编程详解一服务端与客户端的双向对话 小试牛刀1委托声明的关键字和委托方法使用的方法名是不一样的名称 可读性有时委托的名称可能描述了它的用途或它在哪里被使用而方法的名称可能更具体地描述了它的功能。将两者分开可以使代码更具可读性。重用性同一个方法可以被多个不同的委托使用。如果你有一个通用的方法它可以被多个不同的操作触发那么将这些操作定义为不同的委托可能是有意义的。封装性委托可以封装方法的调用使你可以在不改变原始方法的情况下更改其调用方式例如添加额外的日志记录或错误处理。事件在C#中事件是基于委托的。将事件名称与触发事件的方法名称分开是一种常见的做法因为事件通常表示某种更高层次的概念如“数据已更改”或“操作已完成”而方法可能只是实现这个概念的具体细节。
总的来说将委托和方法的名称分开并不是必须的但它可以提供更好的可读性、重用性和封装性。然而在大多数情况下重要的是保持它们之间的签名一致以确保它们可以正确地相互引用和使用。 小试牛刀2对Main方法的理解 这段代码是C#中Windows Forms应用程序的入口点通常在Program.cs文件中找到。我将为你逐步解释这段代码 static void Main(): 这是C#应用程序的入口点。当你运行一个C#控制台应用程序或Windows Forms应用程序时Main方法是首先被调用的。 Application.EnableVisualStyles();: 这行代码使Windows Forms控件能够使用XP和后续版本的Windows中的视觉样式。这意味着控件将具有与操作系统主题一致的外观和感觉。默认情况下如果你不调用此方法Windows Forms控件可能会使用较旧的、不太吸引人的样式。 Application.SetCompatibleTextRenderingDefault(false);: 这行代码告诉Windows Forms应用程序使用GDI进行文本渲染而不是GDI。GDI是GDI图形设备接口的一个增强版本它提供了更丰富的图形和文本渲染功能。设置此属性的值为false通常与EnableVisualStyles一起使用以确保文本和图形都以最佳方式呈现。在某些情况下如果你的应用程序需要兼容旧的Windows版本或特定的文本渲染行为你可能需要将此值设置为true。但在现代Windows Forms应用程序中通常将其设置为false。 Application.Run(new FrmTCPServer());: 这行代码启动Windows Forms应用程序的消息循环并显示FrmTCPServer窗体。Application.Run是Windows Forms应用程序的核心。它启动一个消息循环该循环监听来自操作系统的消息如鼠标单击或键盘按键并将这些消息传递给相应的窗体或控件进行处理。在这里你创建了一个新的FrmTCPServer窗体实例并将其传递给Application.Run方法。这意味着当你运行此应用程序时FrmTCPServer窗体将首先被显示。
简而言之这段代码设置了Windows Forms应用程序的视觉样式和文本渲染方式并启动了应用程序显示FrmTCPServer窗体。 小试牛刀3对方法的理解 private void RecMsg(string str) {this.txt_Rcv.AppendText(strEnvironment.NewLine);}
在这段代码中RecMsg 是一个方法函数它被设计为接收一个字符串参数 str。该方法的主要功能是将传入的字符串 str 添加到 txt_Rcv 这个控件很可能是 Windows Forms 中的 TextBox 控件的文本末尾并在其后添加一个换行符。
这里的 Environment.NewLine 是一个静态属性它返回当前环境的换行符字符串。在 Windows 系统上这通常是 \r\n回车和换行符的组合而在 Unix 和 Linux 系统上它通常是 \n只有换行符。
这里是一个简单的解释
RecMsg 方法被调用时传入一个字符串 str。方法内部使用 this.txt_Rcv.AppendText 将 str 添加到 txt_Rcv 控件的当前文本末尾。接着在 str 的后面添加一个换行符这是通过 Environment.NewLine 实现的。这样每次调用 RecMsg 方法时都会在 txt_Rcv 控件中看到新添加的一行文本。
如果 txt_Rcv 是一个 TextBox 控件并且这个 RecMsg 方法是在 Windows Forms 应用程序的某个窗体中定义的那么这个方法通常会被用于处理接收到的消息并将这些消息显示在窗体上的文本框中。例如在 TCP/IP 聊天应用程序中服务器或客户端可能会调用这个方法来显示从另一端接收到的消息。 小试牛刀4对监听核心代码的理解 sock new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress address IPAddress.Parse(this.txt_IP.Text.Trim());
IPEndPoint endpoint new IPEndPoint(address, int.Parse(this.txt_Port.Text.Trim()));
1.AddressFamily地址族
地址族是一个用来表示IP地址类型的枚举。在您提供的代码中AddressFamily.InterNetwork 表示的是 IPv4 地址族。这意味着您创建的套接字将用于处理 IPv4 类型的网络地址。
AddressFamily.InterNetwork: 表示 IPv4 地址族。AddressFamily.InterNetworkV6: 表示 IPv6 地址族。
2.SocketType套接字类型
套接字类型定义了套接字的基本通信特性。在您提供的代码中SocketType.Stream 表示一个流套接字它通常用于面向连接的通信如 TCP。流套接字提供了一种可靠的、基于字节流的通信方式。
SocketType.Stream: 字节流套接字通常用于 TCP 通信。SocketType.Dgram: 数据报套接字通常用于 UDP 通信。还有其他的套接字类型如 SocketType.Raw 和 SocketType.Rdm但它们通常用于更底层的网络编程。
3.ProtocolType协议类型
协议类型定义了套接字所使用的具体协议。在您提供的代码中ProtocolType.Tcp 表示使用 TCP 协议。TCP 是一种面向连接的、可靠的、基于字节流的传输层协议。
ProtocolType.Tcp: 传输控制协议TCP。ProtocolType.Udp: 用户数据报协议UDP。还有其他协议类型但 TCP 和 UDP 是最常用的。
4.IPEndPoint
IPEndPoint 是一个表示网络端点的类它包含了一个 IP 地址和一个端口号。在您提供的代码中您创建了一个 IPEndPoint 对象其中 address 是一个 IP 地址可能是 IPAddress 类型的实例或可以转换为 IPAddress 的字符串而端口号则是从 txt_Port.Text可能是一个文本框控件的内容中解析出来的整数。
综上所述您提供的代码创建了一个用于 TCP 通信的 IPv4 套接字并指定了一个网络端点IP 地址和端口号。这样您就可以使用这个套接字来与指定的 IP 地址和端口上的服务器或客户端进行通信了。 小试牛刀5对绑定端口号代码的理解 sock.Bind(endpoint);Invoke(myRcvMsg, 服务器开启成功);MessageBox.Show(开启服务成功, 打开服务);
1.端口号绑定 (sock.Bind(endpoint);) 在套接字编程中Bind 方法用于将套接字与特定的本地地址IP 地址和端口号相关联。这告诉操作系统当有数据到达该 IP 地址和端口时应该将数据传递给这个套接字。在您提供的代码中endpoint 是一个 IPEndPoint 对象它包含了 IP 地址和端口号。sock.Bind(endpoint); 就是将套接字 sock 绑定到这个 endpoint 上。
2.Invoke 方法 在 Windows Forms 应用程序中如果你尝试在不是由控件创建的线程上直接更新控件例如在后台线程中更新 UI那么你会遇到线程安全问题并可能导致异常。为了避免这种情况你可以使用控件的 Invoke 方法来在控件的创建线程上执行代码。 这里 myRcvMsg 应该是一个委托实例它指向一个方法该方法接受一个字符串参数在这里是 服务器开启成功。
3.MessageBox.Show 方法 MessageBox.Show 方法用于显示一个消息框。它可以有不同的重载版本接受不同数量的参数。在您提供的代码中MessageBox.Show(开启服务成功, 打开服务); 使用了两个参数
第一个参数 开启服务成功 是要显示的消息文本。第二个参数 打开服务 是消息框的标题。 总结起来您的代码首先绑定套接字到指定的 IP 地址和端口然后尝试使用 Invoke 方法来更新 UI尽管这里的具体实现可能不完全正确最后使用 MessageBox.Show 方法来显示一个消息框。如果您的目的是在 UI 线程上显示消息框那么通常不需要使用 Invoke 来包装 MessageBox.Show 调用因为 MessageBox.Show 本身是线程安全的并且会自动在 UI 线程上执行。
针对这个MessageBox.Show()方法有个地方会经常用到就是捕捉异常的时候 根据下面这个代码理解这个方法 这里是一个catch捕捉异常此处的MessageBox.Show()方法里面的ex.Message会弹出什么内容呢是不是MessageBox.Show方法会根据不同的异常弹出不一样的内容吗catch(Exception ex) { MessageBox.Show(开启服务失败 ex.Message, 打开服务); return; } 在C#中catch(Exception ex) 语句用于捕获在try块中抛出的任何异常。当异常被捕获时ex在这里是一个Exception类型的变量将包含有关该异常的详细信息。 ex.Message 属性包含了异常的描述性消息这个消息通常描述了异常发生的原因。这个消息是由抛出异常的代码生成的可能是一个通用的描述如“发生了一个未处理的异常”也可能是一个更具体的描述如“无法连接到数据库服务器”或“索引超出了数组的范围”。 在你的catch块中MessageBox.Show(开启服务失败 ex.Message, 打开服务); 这行代码将会弹出一个消息框标题为“打开服务”而消息内容为“开启服务失败”后面跟上ex.Message的内容。 因此确实MessageBox.Show() 方法会根据不同的异常弹出不一样的内容因为ex.Message的内容会根据抛出的具体异常而变化。 例如如果抛出的异常是因为网络问题导致的ex.Message 可能会是类似于“无法连接到远程服务器”这样的消息。那么用户将会看到一个消息框内容是“开启服务失败无法连接到远程服务器”标题是“打开服务”。 如果抛出的异常是因为数组越界ex.Message 则可能会是“索引超出了数组的范围”那么用户将会看到一个消息框内容是“开启服务失败索引超出了数组的范围”标题是“打开服务”。 小试牛刀6对socket对象.Listen(10)的理解 在网络编程中特别是使用TCP/IP套接字Socket时sock.Listen(10); 这行代码表示服务器套接字sock现在准备好开始监听来自客户端的连接请求并且它有一个“挂起连接队列”的容量大小为10。
这里是这行代码的详细解释
sock: 这是一个服务器套接字对象通常是在创建套接字使用如Socket类的构造函数并绑定到一个特定的IP地址和端口号后得到的。Listen: 这是Socket类的一个方法用于将套接字置于监听模式以便它可以接受来自客户端的连接请求。10: 这是传递给Listen方法的参数它指定了挂起连接队列的最大长度。挂起连接队列是一个内部数据结构用于存储来自客户端的连接请求当服务器太忙而不能立即接受连接时。队列中的每个条目都代表一个尚未被Accept方法处理的连接请求。
在这个例子中如果服务器套接字sock同时收到超过10个连接请求并且它还没有通过Accept方法接受任何连接那么第11个及以后的连接请求将会被丢弃或拒绝直到队列中有空间为止。
注意仅仅调用Listen方法并不会使服务器自动接受连接。你需要在一个单独的线程或使用异步方法中调用Accept方法以便在连接请求到达时进行处理。Accept方法将从挂起连接队列中取出一个连接请求并返回一个新的套接字对象该对象表示与客户端的已建立连接。然后你可以使用这个新的套接字对象与客户端进行通信。