我们先把前面的代码封装成一个完整的类,因为跟网络相关的方法并不一定是建立socket的服务器和客户端,所以还是应该把两个分开,比如获取本机IP,修改本机IP,PING远程主机这些事情应该放在一个单独的类里面,而且里面的方法应该是静态的(一个应用不会需要多个实例来做上面讲的这些事情),所以我个人建议做成一个单独的类FunctionNetwork,这样可以让主程序很简洁

 

注意可能涉及到IP地址自动获取和手动修改的方法,需要额外的DLL引用(System.Management),这部分功能暂时用不上

 

封装客户端的Socket类方法比较简单,大部分只要照抄前面的代码即可。但是在接收数据的时候我们使用了委托的方法对外传递数据。一般事件和委托成对使用比较方便(先不要管为什么这么写,照着抄就行了),delegate部分声明委托的名称和要传递数据的类型,event部分声明事件的名称。这个socket客户端的事件也就三种(连接成功,收到数据,断开连接,当然你也可以定义额外的事件,比如发送成功也算事件,发送失败也算事件)

 

当socket客户端已经OnRecieveMessageFromServerSuccess(收到的消息)发出去的时候,那么问题来了,谁来处理这个数据?我们当前的程序是需要主程序去处理,所以主程序在初始化的时候,只要声明当TheClient发生XXX事件的时候,就把他要传递的变量通过 +=的函数执行一次(注意用Tab自动补全,)然后就可以拿着这个类要传递的数据显示到控件上了。可以想象,如果不是Form1要用,而是其他的类或者窗体要用,也只要初始化的时候添加一条委托事件的绑定函数就可以了,确实非常方便(不然你怎么把某个类的某个方法产生的数据往外发?委托和事件就是为了解决这个问题来的)

 

还没有完,我们前面介绍的直接更新界面的数据,是通过关闭跨线程访问控件检测实现的,实际上这样做还不规范,实际上当主程序收到消息要更新控件之前,先判断XXX控件是否InvokeRequired,然后如果没有要执行Invoke方法,它里面的写法比较难看懂,也不需要理解,只要能照着葫芦画瓢就行了

 

与之对应的,另外两个委托的方法也是这样做(即便有多个控件要更新,也只需要考虑一个控件.InvokeRequired即可)

 

为了更清晰的看到从Server端发过来的数据,可以用字符串遍历出来(例如服务器发送一个字符A,其实除了这个字符还包括了回车换行 \r\n),可以看到我们定义的byte数组只有前面三位是有意义的(分别是65/13/10),查ASCII码表可以发现就是A+回车+换行(所以如果要解决中文乱码的问题,也需要响应的写转成byte和从byte提取,可能一个byte不足以表示一个中文,而大部分软件只认为传过来一个一个byte就是一个字符,所以强硬的把两个或者更多byte凑在一起才有意义的中文拆了导致的乱码)

 

当服务器断开连接的时候,实际上还是会发送一个空消息(当然你自己写服务器的或者客户端的时候也可以发送自定义消息),还是前面的方法可以测试出来,不管在服务器端点了StopListening直接停止服务器,还是Disconnect仅仅踢掉这个客户端,客户端都还能最后收到一笔byte数组,而这个数组里面啥也没有,这条消息就可以用来判断是不是服务器主动断开了连接

 

所以我们可以把软件做的比较完善,如果是服务器点击的断开连接,则提示服务器主动断开,如果是客户端点击的端口,则提示客户端要断开

 

而且不管是主动还是被动的断开连接,界面的按钮都要重置为连接可用,断开不可用,发送不可用(如果连接成功则相反),所以这也是用委托和事件的方式封装整个类的可能行为及触发的其他方法优势所在,如果不用事件和委托,这些事情也能做,但是要花费的代码和维护,修改的成本会大得多。

 

 

更多教学视频和资料下载,欢迎关注以下信息:

我的优酷空间:

http://i.youku.com/acetaohai123

 

我的在线论坛:

http://csrobot.gz01.bdysite.com/

 

问题交流:

QQ:910358960

邮箱:acetaohai123@163.com

 

 

 

C#应用视频教程1.3 Socket通信客户端完善的更多相关文章

  1. C#应用视频教程1.2 Socket通信客户端实现

    接下来我们尝试实现最简单的Socket客户端,为了确保只可能你的代码有问题,服务器要先用别人成熟的代码测试(这也是编程的一个技巧,先不要用自己写的客户端测试自己写的服务器,这样出了问题你也不知道谁有问 ...

  2. c++ 网络编程(一)TCP/UDP windows/linux 下入门级socket通信 客户端与服务端交互代码

    原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9601511.html c++ 网络编程(一)TCP/UDP  入门级客户端与服务端交互代码 网 ...

  3. Socket通信客户端和服务端代码

    这两天研究了下Socket通信,简单实现的客户端和服务端代码 先上winfrom图片,客户端和服务端一样 服务端代码: using System; using System.Collections.G ...

  4. c# socket通信较完善方案

    c#的socket通信应用.文件较多.附件为工程.  core   AbstractBytesWorker.cs    字节工作器(基类),用于用于同一不同功能的字节工作器  BinaryHand.c ...

  5. Socket通信客户端设计(Java)

    public class Client extends JFrame implements Runnable{ private JPanel jPanel= new JPanel(); private ...

  6. Socket通信-客户端

    WSADATA wsd; SOCKET sHost; SOCKADDR_IN servAddr; if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) retu ...

  7. php的socket通信

    socket通常叫做'套接字',用于描述IP地址和端口,是一个通信链的句柄.应用程序通过套接字向网络发出请求或者应答忘了请求.socket既不是程序,也不是协议,其只是操作系统提供的通信层的一组抽象A ...

  8. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-简单例子-实现简单的服务端客户端消息应答

    一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...

  9. JAVA基础知识之网络编程——-TCP/IP协议,socket通信,服务器客户端通信demo

    OSI模型分层 OSI模型是指国际标准化组织(ISO)提出的开放系统互连参考模型(Open System Interconnection Reference Model,OSI/RM),它将网络分为七 ...

随机推荐

  1. 【UOJ 179】 #179. 线性规划 (单纯形法)

    http://uoj.ac/problem/179 补充那一列修改方法: 对于第i行: $$xi=bi-\sum Aij*xj$$    $$=bi-\sum_{j!=e} Aij*xj-Aie*xe ...

  2. 【UOJ 80】 二分图最大权匹配

    [分析] 之前打的那种KM会TLE... why??明明说n^3的啊? #include<cstdio> #include<cstdlib> #include<cstri ...

  3. Linux下对拍脚本

    使用说明:        1. 被测代码.正确代码.生成器代码均使用文件输入输出: 2. 对拍前会清屏,请注意:        3. 输出文件的文件名请和代码文件名保持一致:        4. 若无 ...

  4. logN判点是否在凸多边形内 HRBUSTOJ1429

    就是利用叉积的性质,如果向量A1到向量A2是顺时针则叉积为负反之为正. 然后我们可以二分的判断找到一个点恰被两条射线夹在一起. 然后我们再判断是否l,r这两个点所连直线与点的关系. 具体资料可以参照这 ...

  5. [转] Android 命名规范 (提高代码可以读性)

    Android命名规范编码习惯 刚接触android的时候,命名都是按照拼音来,所以有的时候想看懂命名的那个控件什么是什么用的,就要读一遍甚至好几遍才知道,这样的话,在代码的 审查和修改过程中就会浪费 ...

  6. [置顶] think in java interview-高级开发人员面试宝典(三)

    收集自Oracle公司的10次(60道)电话面试全部问答(英语) Q: What environment variables do I need to set on my machine in ord ...

  7. vue2.0中引入UEditor的一些坑。。。。

    开发后台系统的时候,富文本编辑器肯定是必不可少的,然后呢~在天朝当然要属百度编辑器(UEditor)最成熟了,功能全面,文档齐全(相对),ui优美(...,对于程序员来说)等等许多方面(MMP,还不是 ...

  8. promise和Rxjs的一点区别

    promise 代码 let promise = new Promise( (resolve) => { setTimeout(() => { resolve('chen'); },200 ...

  9. 【php】利用php的构造函数与析构函数编写Mysql数据库查询类 (转)

    上次在<[php]利用原生态的JavaScript Ajax为php进行MVC分层设计,兼容IE6>(点击打开链接) 一文中,对于php查询Mysql数据库的model.php写法还不够完 ...

  10. PHP 输出数据库中文是问号