Windows平台TCP通信程序实现-基于MFC CSocket类

来源:互联网 发布:python入门到精通 编辑:程序博客网 时间:2024/06/03 13:43

1 软件设计目的

      TCP通信是网络通信方式中最常用的一种,TCP协议位于OSI七层参考模型中的第四层传输层(从下向上,物理层、数据链路层、网络层、传输层),一般基于C/S模式的网络通信服务程序都是通过TCP进行通信,目前在物联网中的应用也十分广泛,网站使用的HTTP协议底层使用的也是TCP协议,因此对TCP通信过程的理解和实现有助相关开发人员快速有效实现TCP通信和解决相关问题。本软件设计一方面能够促进读者对TCP相关知识的理解和掌握,另一方面可以在本文的基础上快速实现TCP通信相关的定制化需求,同时本文能够提供一个TCP通信的客户端调试工具,帮助进行TCP通信的调试开发。

      软件设计的目标是实现一个运行于Windows系统的TCP通信的客户端软件,能够通过IP地址和端口连接到相应的TCP服务器,并能够发送和接收消息。


2 软件设计原理和方案

      软件基于微软MFC应用程序,使用C++语言进行设计,MFC是基于消息映射和消息处理框架的,虽然在发布的时间上确实是过于久了,技术也不再新潮了,可以在满足应用需要的时候也是可以使用的,有时我们在技术的选择上停留了太久,适合就好,是时候启航了,我比较认同的是好的框架和技术是迭代演化而来的,不是一开始就有的。现在很多语言框架本质上都是基于消息驱动或者事件驱动的,包括Java和JS,随便说一句微软现在依然保持着对MFC的支持和维护。本文主要分享一些编程时遇到的问题和解决思路。

      CSocket类是MFC中程序进行网络通信的封装接口,主要用于TCP和UDP通信,CSocket类继承于CAsyncSocket,这两个类的封装大大简化了我们进行网络通信编程的实现,除了提供基本的发送和接收函数,也提供了用于异步消息处理的函数,如OnAccept和OnReceive,这种事件驱动消息响应的处理方式能够提高CPU的利用率,是一种理想高效的编程模型。具体可参考微软官方网站 CAsyncSocket 和 CSocket 。


3 遇到的问题和解决方法

      (1)VS2015项目属性:多字节字符集和Unicode字符集

      多字节字符集是ASCII 字符集的扩展,兼容ASCII字符集,原ASCII字符表示方式相同,扩展字符(包括日文、汉字等)使用多个字节表示,使用前导字节与原ASCII字符区别。

      标准Unicode字符集是所有字符固定使用两个字节表示,称为UTF-16,是国际标准。

      UTF-8是可变长字符集,UTF-8用1到6个字节编码标准Unicode字符(UTF-16),是国际标准。

      使用Unicode字符集出现的问题:

      会出现只收到一个字符的情况,或者只能正确接收一半的字符,或者接收到多出一倍的错误字符。

      问题分析:

      Unicode字符集固定使用两个字节表示一个字符,表示原ASCII字符时两个字节中有一个字节全为零,使用非Unicode接收时程序会把全零的字符当作字符串的结束符处理,会出现只接收到一个字符的情况。

      Unicode字符集固定使用两个字节表示一个字符,在发送或者接收时,很容易把字符的个数与字节的个数混淆,这时就会出现只能正确接收一半的字符,或者接收到多出一倍的错误字符。

      解决办法:

      发送和接收程序同时使用Unicode字符集,或者同时使用多字节字符集。为了兼容更多的TCP通信应用(主要时国内汉字发送接收和显示),建议选择同时使用多字节字符集,本文设计的TCP通信客户端程序使用的就是多字节字符集。未来应该更多的使用UTF-8字符集。

      (2)视图和套接字的模块分离

      需求分析:视图类(对话框类)需要调用套接字类进行服务器连接和数据发送,套接字类需要调用视图类显示接收到的数据,两者之间需要进行数据共享和操作交互。

      解决方法1:两者同时创建一个实例对象,对象拥有相同的生命周期,两者同时保存一个指向对方的指针,通过指针进行相互访问。虽然解决了原始需求,但是两者之间的耦合程度很大,模块的独立性不高,工程的扩展和维护会越来越难。

      解决方法2:把套接字类的唯一一个对象作为视图类的一个成员变量,套接字类只向视图类暴露功能封装完好的公共接口。通过自定义的消息和消息处理函数解决数据和操作的反向传递过程,套接字对象接收到TCP数据时,通过向视图类发送一条自定义消息,并通过额外参数来传递数据存放地址(指针),由视图类在消息处理函数中决定如何显示接收到的TCP数据。这样做提高了模块的独立性,每个模块有自己的决定权和处理职责范围,只暴露必要的接口或者提供必须的服务,便于扩展和维护。


4 软件实现和测试

      (1)如下图所示,TCP服务器的IP地址为127.0.0.1(即本地地址localhost,测试时服务器和客户端在同一电脑上),监听端口为6868。

      客户端IP地址就是本机地址,客户端连接服务器时,操作系统会自动的分配空闲端口号,图中操作系统为本机TCP客户端分配的端口号为13675。


      (2)服务器的连接地址不仅可以是服务器的IP地址,也可以是服务器的域名,只要域名能相应的解析到服务器上即可。如下图所示,其中“ruosu.cf”是域名地址,同样可以连接成功。



5 TCP通信客户端下载地址

      TCP通信客户端为exe可执行文件,可以作为TCP通信调试工具使用,下载地址:TCP通信客户端下载-Windows版


6 软件源代码下载

      工程使用Visual Studio 2015建立,基于MFC对话框工程,建立工程时需要添加“socket”支持,完整工程文件下载地址:TCP通信客户端源代码下载-Windows版,下载密码:dsuv


      软件问题或建议联系邮箱:ruosuprime@foxmail.com