文章目录

  • 一、源代码说明
  • 二、概述
  • 三、通信的报文格式
  • 四、socket通信客户端
  • 五、socket通信的服务端
  • 六、示例程序
    • 1、客户端
    • 2、服务端
    • 3、运行程序前的准备端
    • 4、运行程序
  • 七、socket通信的函数
    • 1、TcpRead函数
    • 2、TcpWrite函数
    • 3、Readn函数
    • 4、Writen函数
  • 八、获取视频教程
  • 九、版权声明

一、源代码说明

freecplus是一个Linux系统下的C/C++开源框架,源代码请前往C语言技术网(www.freecplus.net)下载。

本文介绍的是freecplus框架的TCP/IP协议网络通信的函数和类。

函数和类的声明文件是freecplus/_freecplus.h。

函数和类的定义文件是freecplus/_freecplus.cpp。

示例程序位于freecplus/demo目录中。

编译规则文件是freecplus/demo/makefile。

二、概述

freecplus框架对socket通信封装如下:

CTcpClient类:socket通信的客户端类。

CTcpServer类:socket通信的服务端类。

TcpRead函数:接收socket的对端发送过来的数据。

TcpWrite函数:向socket的对端发送数据。

Readn函数:从已经准备好的socket中读取数据。

Writen函数:向已经准备好的socket中写入数据。

在阅读本文章之前,您必须熟悉TCP/IP协议和socket通信,本文是介绍的是freecplus框架中网络通信的类和函数的用法,不会介绍网络通信的基础知识。

三、通信的报文格式

freecplus框架的socket通信报文格式如下:

报文长度+报文内容

报文长度为4字节的整数,表示的是报文内容的长度,而不是整个TCP报文的长度,整个TCP报文的长度是报文内容的长度+4

报文长度是4字节的整数,即int,是以二进制流的方式写入socket,不是ascii码。

采用CTcpClient类、CTcpServer类、TcpRead函数和TcpWrite函数进行socket通信,可以避免TCP报文粘包的问题。

四、socket通信客户端

socket通信的客户端封装在CTcpClient类中。

类的声明:

// socket通信的客户端类
class CTcpClient
{public:int  m_sockfd;    // 客户端的socket.char m_ip[21];    // 服务端的ip地址。int  m_port;      // 与服务端通信的端口。bool m_state;     // 与服务端的socket连接状态。bool m_btimeout;  // 调用Read和Write方法时,失败的原因是否是超时:true-未超时,false-已超时。int  m_buflen;    // 调用Read方法后,接收到的报文的大小,单位:字节。CTcpClient();  // 构造函数。// 向服务端发起连接请求。// ip:服务端的ip地址。// port:服务端监听的端口。// 返回值:true-成功;false-失败。bool ConnectToServer(const char *ip,const int port);// 接收服务端发送过来的数据。// buffer:接收数据缓冲区的地址,数据的长度存放在m_buflen成员变量中。// itimeout:等待数据的超时时间,单位:秒,缺省值是0-无限等待。// 返回值:true-成功;false-失败,失败有两种情况:1)等待超时,成员变量m_btimeout的值被设置为true;2)socket连接已不可用。bool Read(char *buffer,const int itimeout=0);// 向服务端发送数据。// buffer:待发送数据缓冲区的地址。// ibuflen:待发送数据的大小,单位:字节,缺省值为0,如果发送的是ascii字符串,ibuflen取0,如果是二进制流数据,ibuflen为二进制数据块的大小。// 返回值:true-成功;false-失败,如果失败,表示socket连接已不可用。bool Write(const char *buffer,const int ibuflen=0);// 断开与服务端的连接void Close();~CTcpClient();  // 析构函数自动关闭socket,释放资源。
};

五、socket通信的服务端

socket通信的服务端封装在CTcpServer类中。

类的声明:

// socket通信的服务端类
class CTcpServer
{private:int m_socklen;                    // 结构体struct sockaddr_in的大小。struct sockaddr_in m_clientaddr;  // 客户端的地址信息。struct sockaddr_in m_servaddr;    // 服务端的地址信息。
public:int  m_listenfd;   // 服务端用于监听的socket。int  m_connfd;     // 客户端连接上来的socket。bool m_btimeout;   // 调用Read和Write方法时,失败的原因是否是超时:true-未超时,false-已超时。int  m_buflen;     // 调用Read方法后,接收到的报文的大小,单位:字节。CTcpServer();  // 构造函数。// 服务端初始化。// port:指定服务端用于监听的端口。// 返回值:true-成功;false-失败,一般情况下,只要port设置正确,没有被占用,初始化都会成功。bool InitServer(const unsigned int port); // 阻塞等待客户端的连接请求。// 返回值:true-有新的客户端已连接上来,false-失败,Accept被中断,如果Accept失败,可以重新Accept。bool Accept();// 获取客户端的ip地址。// 返回值:客户端的ip地址,如"192.168.1.100"。char *GetIP();// 接收客户端发送过来的数据。// buffer:接收数据缓冲区的地址,数据的长度存放在m_buflen成员变量中。// itimeout:等待数据的超时时间,单位:秒,缺省值是0-无限等待。// 返回值:true-成功;false-失败,失败有两种情况:1)等待超时,成员变量m_btimeout的值被设置为true;2)socket连接已不可用。bool Read(char *buffer,const int itimeout);// 向客户端发送数据。// buffer:待发送数据缓冲区的地址。// ibuflen:待发送数据的大小,单位:字节,缺省值为0,如果发送的是ascii字符串,ibuflen取0,如果是二进制流数据,ibuflen为二进制数据块的大小。// 返回值:true-成功;false-失败,如果失败,表示socket连接已不可用。bool Write(const char *buffer,const int ibuflen=0);// 关闭监听的socket,即m_listenfd,常用于多进程服务程序的子进程代码中。void CloseListen();// 关闭客户端的socket,即m_connfd,常用于多进程服务程序的父进程代码中。void CloseClient();~CTcpServer();  // 析构函数自动关闭socket,释放资源。
};

六、示例程序

1、客户端

示例(demo47.cpp)

/**  程序名:demo47.cpp,此程序演示采用freecplus框架的CTcpClient类实现socket通信的客户端。*  作者:C语言技术网(www.freecplus.net) 日期:20190525
*/
#include "../_freecplus.h"int main(int argc,char *argv[])
{CTcpClient TcpClient;   // 创建客户端的对象。if (TcpClient.ConnectToServer("172.16.0.15",5858)==false) // 向服务端发起连接请求。{printf("TcpClient.ConnectToServer(\"172.16.0.15\",5858) failed.\n"); return -1;}char strbuffer[1024];    // 存放数据的缓冲区。for (int ii=0;ii<5;ii++)   // 利用循环,与服务端进行5次交互。{memset(strbuffer,0,sizeof(strbuffer));snprintf(strbuffer,50,"这是第%d个超级女生,编号%03d。",ii+1,ii+1);printf("发送:%s\n",strbuffer);if (TcpClient.Write(strbuffer)==false) break;    // 向服务端发送请求报文。memset(strbuffer,0,sizeof(strbuffer));if (TcpClient.Read(strbuffer,20)==false) break;  // 接收服务端的回应报文。printf("接收:%s\n",strbuffer);sleep(1);}// 程序直接退出,析构函数会释放资源。
}

2、服务端

示例(demo48.cpp)

/**  程序名:demo48.cpp,此程序演示采用freecplus框架的CTcpServer类实现socket通信的服务端。*  作者:C语言技术网(www.freecplus.net) 日期:20190525
*/
#include "../_freecplus.h"int main(int argc,char *argv[])
{CTcpServer TcpServer;   // 创建服务端对象。if (TcpServer.InitServer(5858)==false) // 初始化TcpServer的通信端口。{printf("TcpServer.InitServer(5858) failed.\n"); return -1;}if (TcpServer.Accept()==false)   // 等待客户端连接。{printf("TcpServer.Accept() failed.\n"); return -1;}printf("客户端(%s)已连接。\n",TcpServer.GetIP());char strbuffer[1024];  // 存放数据的缓冲区。while (true){memset(strbuffer,0,sizeof(strbuffer));if (TcpServer.Read(strbuffer,300)==false) break; // 接收客户端发过来的请求报文。printf("接收:%s\n",strbuffer);strcat(strbuffer,"ok");      // 在客户端的报文后加上"ok"。printf("发送:%s\n",strbuffer);if (TcpServer.Write(strbuffer)==false) break;     // 向客户端回应报文。}printf("客户端已断开。\n");    // 程序直接退出,析构函数会释放资源。
}

3、运行程序前的准备端

我希望您已经学过计算机网络的基础知识,在运行示例程序之前,请确保您的Linux操作系统已开通防火墙。

在demo47.cpp和demo48.cpp程序中,服务端的ip地址和通信端口是写死在程序中的,请根据您的实际情况修改它们,然后重新编译。

4、运行程序

先启动demo48,然后启动demo47。

demo47的运行效果如下:

demo48的运行效果如下:

七、socket通信的函数

采用CTcpClient和CTcpServer类实现socket通信功能非常方便,但是在实际开发中,某些场景中不能只依赖这两个类,例如多程线和异步通信等场景,还必须结合以下将要介绍的几个函数一起使用。

1、TcpRead函数

接收socket的对端发送过来的数据。

函数的声明:

bool TcpRead(const int sockfd,char *buffer,int *ibuflen,const int itimeout=0);

参数说明:

sockfd:可用的socket连接。

buffer:接收数据缓冲区的地址。

ibuflen:本次成功接收数据的字节数。

itimeout:接收等待超时的时间,单位:秒,缺省值是0-无限等待。

返回值:true-成功;false-失败,失败有两种情况:1)等待超时;2)socket连接已不可用。

在CTcpClient和CTcpServer类的Read方法中调用了TcpRead函数。

2、TcpWrite函数

向socket的对端发送数据。

函数的声明:

bool TcpWrite(const int sockfd,const char *buffer,const int ibuflen=0);

参数说明:

sockfd:可用的socket连接。

buffer:待发送数据缓冲区的地址。

ibuflen:待发送数据的字节数,如果发送的是ascii字符串,ibuflen取0,如果是二进制流数据,ibuflen为二进制数据块的大小。

返回值:true-成功;false-失败,如果失败,表示socket连接已不可用。

在CTcpClient和CTcpServer类的Write方法中调用了TcpRead函数。

3、Readn函数

从已经准备好的socket中读取数据。

函数的声明:

bool Readn(const int sockfd,char *buffer,const size_t n);

sockfd:已经准备好的socket连接。

buffer:接收数据缓冲区的地址。

n:本次接收数据的字节数。

返回值:成功接收到n字节的数据后返回true,socket连接不可用返回false。

注意:

1)sockfd是已经准备好的socket连接,那什么是已经准备好的socket?在这个socket上,已经或马上有n字节的数据一定会到达。

2)成功接收到n字节的数据后返回true,如果没有n字节的数据怎么办?不会,在1)中已经说明了,一定会有n字节的数据会到达。

3)如果数据大于n字节怎么办?Readn只读取n个字节的数据,其它的数据属于其它的报文。

4)socket的对端是采用Writen方法写入的数据。

在TcpRead函数中,调用了Readn函数。

4、Writen函数

向已经准备好的socket中写入数据。

函数的声明:

bool Writen(const int sockfd,const char *buffer,const size_t n);

sockfd:已经准备好的socket连接。

buffer:待发送数据缓冲区的地址。

n:待发送数据的字节数。

返回值:成功发送完n字节的数据后返回true,socket连接不可用返回false。

在TcpWrite函数中,调用了Writen函数。

八、获取视频教程

百万年薪程序员录制,《C/C++高性能服务开发基础》视频教程已在CSDN学院发布,优惠价12元,地址如下:
https://edu.csdn.net/course/play/29402

九、版权声明

C语言技术网原创文章,转载请说明文章的来源、作者和原文的链接。
来源:C语言技术网(www.freecplus.net)
作者:码农有道

如果文章有错别字,或者内容有错误,或其他的建议和意见,请您留言指正,非常感谢!!!

freecplus框架-tcp网络通信相关推荐

  1. freecplus框架简介

    文章目录 一.freecplus框架简介 二.freecplus开源许可协议 三.freecplus框架内容 字符串操作 2.xml解析 3.日期时间 4.目录操作 5.文件操作 6.日志文件 7.参 ...

  2. freecplus框架,Linux平台下C/C++程序员提高开发效率的利器

    文章目录 一.freecplus框架简介 二.freecplus开源许可协议 三.freecplus框架内容 字符串操作 2.xml解析 3.日期时间 4.目录操作 5.文件操作 6.日志文件 7.参 ...

  3. 01、freecplus框架简介

    文章目录 一.freecplus框架简介 二.freecplus开源许可协议 三.freecplus框架内容 字符串操作 2.xml解析 3.日期时间 4.目录操作 5.文件操作 6.日志文件 7.参 ...

  4. freecplus框架,Linux平台下C_C++程序员提高开发效率的利器

    文章目录 一.freecplus框架简介 二.freecplus开源许可协议 三.freecplus框架内容 字符串操作 2.xml解析 3.日期时间 4.目录操作 5.文件操作 6.日志文件 7.参 ...

  5. C语言实现TCP网络通信(附服务端和客服端完整源码)

    C语言实现TCP网络通信 服务端源码 客户端源码 服务端源码 #include <stdio.h> #include <stdlib.h> #include <strin ...

  6. tcp网络通信教程 java_基于java TCP网络通信的实例详解

    JAVA中设计网络编程模式的主要有TCP和UDP两种,TCP是属于即时通信,UDP是通过数据包来进行通信,UDP当中就会牵扯到数据的解析和传送.在安全性能方面,TCP要略胜一筹,通信过程中不容易出现数 ...

  7. Nginx加密与上游服务器的TCP网络通信

    Nginx加密与上游服务器的TCP网络通信 本文介绍了如何保护NGINX和TCP上游服务器或TCP服务器上游组之间的TCP通信. 先决条件 NGINX Plus R6和更高版本或使用--with-st ...

  8. 一文搞懂如何使用Node.js进行TCP网络通信

    摘要: 网络是通信互联的基础,Node.js提供了net.http.dgram等模块,分别用来实现TCP.HTTP.UDP的通信,本文主要对使用Node.js的TCP通信部份进行实践记录. 本文分享自 ...

  9. freecplus框架-PostgreSQL数据库操作

    文章目录 一.源代码说明 二.概述 三.connection类 四.sqlstatement类 五.程序流程 1.无结果集SQL的程序的流程 2.有结果集SQL的程序的流程 六.示例程序 1.创建超女 ...

最新文章

  1. linux中搭建vue-cli
  2. eeglab教程系列(14)-Working with ICA Components
  3. python3下载安装配置-Linux 安装python3.7.3
  4. 软件研发的这些误区,你中了吗?
  5. BASIC-12 十六进制转八进制
  6. MySQL date_sub()函数
  7. php 接口有几种,【后端开辟】php接口有哪些范例?
  8. python清空集合_python集合删除多种方法详解
  9. 在阿里云上创建带gpu的ecs实例
  10. 云服务器远程连接的设置方法、安全组设置(外网可访问)
  11. win10开启虚拟化服务器,win10怎么开启vt技术-win10开启vt虚拟化技术的方法 - 河东软件园...
  12. 在LabWindows/CVI中程控的调整表格控件的属性
  13. 华为篇-嵌入式公司待遇盘点-第二期
  14. html中hover的作用,hover在css中的用法
  15. MODULE_DEVICE_TABLE宏的作用
  16. Firefox,火狐about:config设置详解
  17. 京东商品详情数据接口(APP端,H5端),实时了解商品价格走势,接口代码教程
  18. 新能源汽车的电池寿命
  19. 阿里P8总结的Nacos入门笔记,从安装到进阶小白也能轻松学会
  20. CSS——去除iframe边框

热门文章

  1. Python实现大自然数分解为最多4个平方数之和(1)
  2. Python爬虫扩展库scrapy选择器用法入门(一)
  3. linux 优化 sysctl.conf,Linux内核sysctl.conf的优化设置
  4. linux 转码软件,分享|Linux 桌面中 4 个开源媒体转换工具
  5. 体积的2 3科学计算机怎么算,小学三年级上册科学第2课-测量体积教案-冀人版
  6. QT每日一练day15:QColorDialog颜色对话框
  7. C++之new和delete探究
  8. C语言之文件读写探究(五):rewind、ftell、fseek(文件指针偏移)
  9. mysql insert s锁_MySQL 死锁套路:唯一索引 S 锁与 X 锁的爱恨情仇
  10. 临界区设计太大或太小有何缺点_空压机100课之016:离心式压缩机的结构、原理及优缺点...