当前位置: 首页 > news >正文

【Linux】网络基础和socket(4)

1.网络通信(app\浏览器、小程序)

2.网络通信三要素:

IP:计算机在网络上唯一标识(ipv4:4个字段,每段最大255   IPV6:16进制)

端口:计算机应用或服务唯一标识   ssh提供远程安全连接的服务 22  端口范围:1-65535(系统默认服务占用了部分端口,所以我们自己定义的网络应用会选用10000之后的端口)

通信协议:通信双方约定的通信数据的规格

3.网络通信协议:TCP/IP簇

不是一个协议,是由非常多的网络通信协议构成的一整套协议,通常称为协议簇,我们所接触的网络通信应用层通常使用自定义协议

实现TCP/IP协议的软件称为协议栈(移植)

TCP/IP四层协议:应用层、传输层、网络层、数据链路层(OSI网络七层模型)

传输层协议:TCP、UDP区别,应用场景:

TCP:

  • 面向连接:先创建连接,才能通信
  • 通信可靠性高
  • 实时性(通信效率)较低
  • 流式传输,带来问题是粘包(分开两次发,但全合在一起)
  • 应用场景:适用于对安全性,可靠性要求较高的场景中

UDP:

  • 无连接:无需创建连接,就可以通信
  • 通信可靠性低,易丢失
  • 实时性(通信效率)较高
  • 数据包方式,每个数据包是分离的,不粘包
  • 通信用于对实时性要求较高的场景中

4.TCP通信过程:

建立连接(三次握手)

通信过程(反馈+重发

结束连接(四次挥手)

5.TCP编程相关API

5.1、TCP通信框架

(1)C/S(Client/Server,客户端 / 服务器)架构:

C端与S端分别是一套独立软件

  • 性能表现出色:客户端与服务器直接交互,能有效降低网络传输的数据量。在处理复杂业务逻辑和大量数据时,C/S 架构可充分利用客户端的硬件资源,运行速度更快,响应更及时。例如,大型的图形设计软件和专业的金融交易系统,采用 C/S 架构能提供流畅的操作体验。

  • 高度定制化:客户端程序可根据特定用户的需求进行深度定制,能实现复杂的用户界面和交互逻辑。比如,一些企业内部使用的生产管理系统,会根据企业的业务流程和操作习惯,定制独特的功能和界面。

  • 数据安全性高:客户端和服务器之间的数据传输可以采用加密协议,而且客户端程序可以对用户输入的数据进行严格的验证和过滤,减少了数据泄露和恶意攻击的风险。例如,银行的网上交易客户端,通过多种加密技术保障用户资金和交易信息的安全。

(2) B/S(Browser/Server,浏览器 / 服务器)
  • 易于部署和维护:由于客户端只需浏览器,无需安装专门的软件,系统的部署和更新都在服务器端完成,大大降低了维护成本和工作量。例如,企业的办公自动化系统升级时,管理员只需更新服务器端的程序,用户在下次访问时即可使用新功能。

  • 跨平台兼容性好:只要有浏览器,无论使用何种操作系统(如 Windows、Mac OS、Linux),用户都能访问系统。这使得 B/S 架构的应用程序具有更广泛的用户群体。比如,在线教育平台,学生可以使用不同操作系统的设备通过浏览器访问课程。

  • 可访问性强:用户只要有网络连接,就可以在任何地方使用浏览器访问系统,不受地域和设备的限制。例如,销售人员在外出拜访客户时,通过手机浏览器就能实时查询公司的产品信息和客户资料。

5.2、Socket:套接字,用于网络通信之用

主要有两类传输套接字,流式套接字SOCK_STREAM)和数据报套接字SOCK_DGRAM

流式套接字:基于 TCP 协议,适合对可靠性要求高、需要连续数据流的应用,如 HTTPSMTP 等协议

数据报套接字:基于 UDP 协议,无连接,适合发送小数据包且对可靠性要求不高的应用,如音频或视频应用程序。

5.3、网络

5.4、C/S函数实现

(1)创建socket

/*
    * domain域:决定使用什么地址协议(IPV4,IPV6)

                          IPV4使用“AF_INET        IPV6使用“ AF_INET6”
    * type类型:决定了什么通信协议(TCP/UDP)

                         SOCK_STREAM:字节流(流式传输)
    * protocol:一般为0,让系统自动选择
    * 返回值:正确返回非负整数,错误返回-1

*/
    int server_fd = socket(AF_INET, SOCK_STREAM, 0);

(2)绑定端口

//使用sockadd_in需要头文件,可以不写结构体进去

#include <arpa/inet.h>
#include <unistd.h>

//服务端Socket文件描述符,地址,地址结构体长度
    struct sockaddr_in addr = { 0 };
    addr.sin_family = AF_INET;//IPV4
    addr.sin_addr.s_addr = INADDR_ANY;//服务器IP地址(INADDR_ANY让系统选择当前网卡对应的IP地址)
    addr.sin_port = htons(10001);//服务器端口号
    int res= bind(server_fd, (struct sockaddr*)&addr, sizeof(addr));

struct sockaddr_in {

  short int sin_family; /* Internet地址族 */

  unsigned short int sin_port; /* 端口号 */

  struct in_addr sin_addr; /* Internet地址 */

  unsigned char sin_zero[8]; /* 添0(和struct sockaddr一样大小)*/

};

(3)开启监听(文件描述符、最大连接数)

res = listen(server_fd, 10);

(4)等待客户端连接

int client_fd = accept(server_fd, NULL, NULL);

 (5)等待接收客户端数据

int len = read(client_fd, recv, sizeof(recv));

(6)响应数据到客户端

write(client_fd, send, sizeof(send));

(7)关闭连接(服务端一般不关闭)

close(client_fd);

例子:使用套接字+进程实现客户端与服务端之间的通信

服务端:

#include <iostream>
#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>using namespace std;
int main()
{char recv[100] = { 0 };char response[200] = { 0 }; // 新的缓冲区用于存放格式化后的字符串//1.创建socketint server_id = socket(AF_INET, SOCK_STREAM, 0);if (server_id < 0){perror("socket error");return -1;}//2.绑定端口struct sockaddr_in addr = { 0 };addr.sin_family = AF_INET;addr.sin_addr.s_addr = INADDR_ANY;addr.sin_port = htons(10001);int res = bind(server_id, (struct sockaddr*)&addr, sizeof(addr));if (res < 0){perror("bind error");}//3.开启监听res = listen(server_id, 10);if (res < 0){perror("listen error");}cout << "等待客户端连接..." << endl;while (1){//4.等待客户端连接int client_id = accept(server_id, NULL, NULL);cout << "有新客户端连接 client_id" << client_id << endl;int fork_id = fork();if (fork_id == 0){while (1){bzero(recv, sizeof(recv));//5.等待接收客户端数据int len = read(client_id, recv, sizeof(recv));cout << "data=" << recv << endl;sprintf(response, "server: %s is got", recv); // 使用新的缓冲区,不然可能会出错cout << response << endl;//6.响应数据到客户端write(client_id, response, strlen(response)); // 发送格式化后的字符串}}}return 0;
}

客户端:

#include <iostream>
#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>using namespace std;
int main()
{char send[100] = { 0 };char recv[100] = { 0 };int client_id = socket(AF_INET, SOCK_STREAM, 0);if (client_id < 0){perror("socket error");}while (1){//连接struct sockaddr_in addr = { 0 };addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr("127.0.0.1");addr.sin_port = htons(10001);int res = connect(client_id, (struct sockaddr*)&addr, sizeof(addr));if (res < 0){perror("connect12 error");sleep(5);continue;}cout << "连接成功服务端,client_id=" << client_id << endl;while (1){bzero(send, sizeof(send));cout << "请输入请求:" << endl;cin >> send;if (strcmp(send, "ok") == 0){break;}//发送请求write(client_id, send, sizeof(send));//读取反馈read(client_id, recv, sizeof(recv));cout << recv << endl;}close(client_id);}return 0;
}

相关文章:

  • SQL进阶知识:六、动态SQL
  • 济南国网数字化培训班学习笔记-第二组-5节-输电线路设计
  • 解决 PostgreSQL 检查约束导致的数据插入异常问题
  • 网络IP冲突的成因与解决方案
  • 三维重建模块VR,3DCursor,MPR与VR的坐标转换
  • 二叉树的创建,增加,前序遍历
  • Bytebase 取得 SOC 2 Type 1 认证
  • 第55讲:农业人工智能的跨学科融合与社会影响——构建更加可持续、包容的农业社会
  • YOLOv5改进(十)-- 轻量化模型MobileNetv4
  • Sharding-JDBC 系列专题 - 第十篇:ShardingSphere 生态与未来趋势
  • PHYBench:首个大规模物理场景下的复杂推理能力评估基准
  • C++23文本编码革新:迈向更现代的字符处理
  • 2025年3月电子学会青少年机器人技术(五级)等级考试试卷-理论综合
  • 10.接口而非实现编程
  • CentOS 7上Memcached的安装、配置及高可用架构搭建
  • LLM学习笔记4——本地部署Docker、vLLM和Qwen2.5-32B-Instruct实现OpenManus的使用
  • Qt 中线程使用
  • shell练习题(1)
  • 腾讯云服务器安全——服务防火墙端口放行
  • 哈希表Hash table【C++】
  • 牛市早报|特朗普称或将“大幅降低”对华关税,外交部回应
  • “仅退款”将成历史?电商平台集中调整售后规则
  • 上海市闵行区原二级巡视员琚汉铮接受纪律审查和监察调查
  • 厦门国贸去年营收约3544亿元,净利润同比减少67.3%
  • 迎世界读书日,2025年首都大学生系列读书活动发布
  • 广汽全域赋能,领程皮卡概念车重磅登陆上海车展