AI智能
改变未来

基于C# Winform实现简单的Socket客户端

如上图所示为简单的Socket客户端与服务端的通信(使用 NetAssist 网络调试助手作为服务端)。

(思索了一会,想想从哪里讲更容易接收理解,感觉还是要从原理出发更能理解,如有不同的思考方式,请见谅)

上图为最最最常见的Socket TCP/IP通信过程,网上随便一搜都能搜得到的东西,本文章做客户端,我们主要关心左边画了红框部分就可以,但是作为C#开发者,我觉得我更关注的是我画了绿框的部分,因为这两个方法,我们在代码里会出现。

直接看代码:(很认真的每句话都做了注释)

其中 btnCon_Click 为“连接服务器”按钮的单击事件,txtIp 为“服务器地址” 的控件名称,取里面我们自己写的IP地址哈,txtPort 为“服务器端口”的控件名称,取里面我们自己写的端口号地址哈,这里绿框框就对应上了。

再看“断开服务器”的代码(我们一个控件一个控件的看哈!):

上面的代码很简单,就调用一个Close()方法;因为本章做的是简单版的 Socket 客户端,所以这里有个问题就是当断开连接后,再点击“连接服务器”,则会在消息中看到错误异常“无法访问已释放的对象”,这些问题可以在网上搜索解决,本文的重点是实现通信,所以没把软件做到近乎完美的程度,很多BUG还是需要一个一个解决的。

接下来看“发送消息”的代码:

这段代码很简单,就是将消息发送出去,核心的方法是红框里的这个Send()方法,只要调用这个方法,将要发送的转码后的信息作为参数放进去,就会把信息发送到服务端。

接下来就要看对部分人来说会感到头疼的部分了———-接收消息。

我们在本文的第三张图中看到了,我为接收消息开启了一个新的线程,而这个线程跟我们的窗体、包括我们的控件的线程不是一个线程,但是我们希望接收到的消息打印在我们“对话窗口”中(不这么做的话也没什么意义了),此时会面临 跨线程  的问题,按本人所搜索到的信息理解是这样的:假设窗体程序为线程A,而我们新开的线程B用来接收消息,则消息B里的数据要放在线程A中,如果不做一些处理,很可能造成死锁,死锁的原因是因为,当A正在做某些工作时,此时B一脚掺进来,也要在A上做一些事,但A上没那么多位置(资源)去同时做两个事,这时候两件事就“卡”住了,计算机不知道要先解决谁,就会出现死锁问题,所以这里不处理的话,程序会报出跨线程的异常错误。(纯属本人理解,如果错误,请在留言指出,感谢!)

如何解决上面的问题呢?经过搜索,网上大致有两种方式解决:

方法一(Control.CheckForIllegalCrossThreadCalls = false;):

以上代码的核心代码已经红框框框出,其中 Control.CheckForIllegalCrossThreadCalls = false; 只是单纯的将跨线程的异常屏蔽,但没解决实际问题,如果你的软件只是简单使用的话,可以使用这种方法,否则的话不推荐使用,如果要要使用这个方法,则第三张图中的线程那里就要修改一下,Thread revThread = new Thread(LoadRevMsg) 改成 Thread revThread = new Thread(ReceiveMsg) ,此方法也能简单的作为客户端和服务端收发消息使用。

while循环是必须的,不然的话,客户端只能接收到第一次发来的消息,之后就就收不到了。

方法二(委托):(好难用文字描述,叹了口气,还是坚持写完吧!!!)

先看代码,线程调用的方法LoadRevMsg():

核心代码已用红框框框出,其中Receive()就是Socket接收消息的方法,跟上面的Send()方法就当成一对兄弟理解吧,一发一收。

ReceiveMsg(txtMsg)就是我们自己写的方法了,接下来就要使用委托去解决这个跨线程导致的异常了。

看代码,“对话窗口”接收消息调用的方法 ReceiveMsg(string msg):

解释即为图中的注释,这些解释也是在网上搜索,别的大神的解释,看了这些 InvokeRequired 和 Invoke 的元数据注释,只能自己勉强理解,不敢做太多别的解释,以免误导大家。以上就是接收消息的两种方法了。

最后再来个Ending代码:

关闭窗口事件—-将关闭窗口事件绑定这个方法,做到关闭窗口时释放掉这个连接,释放掉资源(及时清理掉还是很好的习惯的)

以上就是基于C# winform的Socket客户端,能实现基本的收发数据,还有许多的BUG待修改,还有许多的功能有待添加,这里只实现了它的核心功能,其他的待继续优化。

本文为作者纯纯纯纯纯纯(省略一万个字)手码字(码了一个小时了),如有雷同,万分荣幸,感谢各位的支持,感谢各位指出错误和不足!!!

 

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 基于C# Winform实现简单的Socket客户端