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

网络编程之TCP编程

基于  C/S :客户端(client)/服务器端(server)

1.流程

       

2.  函数接口

所有函数所需头文件:

#include <sys/types.h> 
#include <sys/socket.h>

系统定义好了用来存储网络信息的结构体

ipv4通信使用的结构体:struct sockaddr_in

我们只需要直接定义结构体变量即可

2.1 创建套接字socket()

int socket(int domain, int type, int protocol);
功能:创建套接字
参数:domain:协议族AF_UNIX, AF_LOCAL  本地通信AF_INET            ipv4AF_INET6            ipv6type:套接字类型SOCK_STREAM:流式套接字SOCK_DGRAM:数据报套接字SOCK_RAW:原始套接字protocol:协议  一般填0 自动匹配底层 根据type系统默认自动帮助匹配对应协议传输层:IPPROTO_TCP、IPPROTO_UDP、IPPROTO_ICMP网络层:htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL)返回值:成功 文件描述符-- > sockfd (用于连接)失败 -1,更新errno

 注意:TCP服务器端有两类文件描述符 !!!
        一类用于连接的文件描述符(sockfd-->socket函数返回值) 只有一个
        一类用于通信的文件描述符(acceptfd-->accept函数返回值) 可以多个

2.2绑定套接字bind()

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:绑定
参数:socket:套接字addr:用于通信结构体 (提供的是通用结构体,需要根据选择通信方式,填充对应结构体-通信当时socket第一个参数确定)   addrlen:结构体大小   
返回值:成功 0   失败-1,更新errno

由于系统定义好的记录网络信息的结构体是struct sockaddr_in类型,因此,bind第二个参数使用时结构体变量地址的时候要强制类型转换

2.3监听listen()

int listen(int sockfd, int backlog);
功能:监听,将主动套接字变为被动套接字
参数:sockfd:套接字backlog:(目前已无具体作用,写个正数即可)同时响应客户端请求链接的最大个数,不能写0.不同平台可同时链接的数不同,一般写6-8个(队列1:保存正在连接)(队列2,连接上的客户端)返回值:成功 0   失败-1,更新errno 

注意:listen作用:主动套接字变为被动套接字!!!

2.4接收客户端连接请求 accept()

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
accept(sockfd,NULL,NULL);
功能:阻塞函数,阻塞等待客户端的连接请求,如果有客户端连接,
则accept()函数返回,返回一个用于通信的套接字文件描述符;
参数:Sockfd :套接字addr: 链接客户端的ip和端口号如果不需要关心具体是哪一个客户端,那么可以填NULL;addrlen:结构体的大小如果不需要关心具体是哪一个客户端,那么可以填NULL;
返回值: 成功:文件描述符; //用于通信失败:-1,更新errno

2.5接受消息recv()

ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能: 接收数据 
参数: sockfd: acceptfd ;buf  存放位置len  大小flags  一般填0,相当于read()函数MSG_DONTWAIT  非阻塞
返回值: < 0  失败出错  更新errno==0  表示客户端退出>0   成功接收的字节个数

2.6发送消息send()

ssize_t send(int sockfd, const void *buf, size_t len, int flags);
功能:发送数据
参数:sockfd:socket函数的返回值buf:发送内容存放的地址len:发送内存的长度flags:如果填0,相当于write();

2.7连接服务器connect()

int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:用于连接服务器;
参数:sockfd:socket函数的返回值addr:填充的结构体是服务器端的;addrlen:结构体的大小
返回值 -1 失败,更新errno正确 0 

2.8 关闭套接字 close()

即关闭套接字文件

close(文件描述符);

3.服务器端

 按照流程:

(1)创建流式套接字socket()

     

(2)指定网络信息

 (3)绑定套接字bind()

(4) 监听listen()

(5) 等待客户连接信息accept()

 注意:

在服务器端使用客户的网络信息时:

(6)收发消息 send() recv()

(7) 关闭套接字

源代码:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>//  $$ 服务器端 $$  int main(int argc, char const *argv[])
{/*创建流式套接字*/int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){perror("socket err");return -1;}else{printf("创建套接字成功\n");}/*指定服务器网络信息 使用的协议族(IPv4-->AF_INET)、IP地址、端口号等*/// 服务器的网络信息通过一个系统定义好的结构体来描述struct sockaddr_in saddr;                     // 定义一个结构体变量saddr.sin_family = AF_INET;                   // 确定协议族-->IPv4saddr.sin_port = htons(atoi(argv[1]));        // 确定使用的端口号saddr.sin_addr.s_addr = inet_addr("0.0.0.0"); // 确定服务器IP地址/*绑定套接字*/int t1 = bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));if (t1 < 0){perror("bind err");return -1;}else{printf("绑定套接字成功\n");}/*监听*/int t2 = listen(sockfd, 6); // 将默认的主动套接字变为被动套接字if (t2 < 0){printf("listen err");return -1;}else{printf("监听中\n");}int acceptfd;char buf[128] = "";int ret;// 定义一个结构体变量来存接收到的客户信息struct sockaddr_in caddr;int len = sizeof(caddr); // len是记录客户信息的结构体的大小while (1){/*阻塞等待接收客户端的连接请求,并将连接成功的客户端信息写入到结构体变量caddr中*/acceptfd = accept(sockfd, (struct sockaddr *)&caddr, &len);if (acceptfd < 0){printf("accept err");return -1;}else{printf("等待接收客户端请求\n");}printf("客户IP:%s 端口号:%d \n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));while (1){/*接收消息*/ret = recv(acceptfd, buf, 128, 0); // 0-->相当于read(acceptfd,buf,128)if (ret < 0){perror("recv err");return -1;}else if (ret == 0){printf("客户退出\n");break;}else{printf("%s 接收成功\n", buf);memset(buf, 0, sizeof(buf));}}close(acceptfd);}/* 关闭套接字 */close(sockfd);return 0;
}

4.客户端

按照流程:

(1)创建流式套接字socket()

(2)指定服务器网络信息

(3)连接服务器connect()

(4)发送接受消息 send()  recv()

(5)关闭套接字

源代码:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
//  $$ 客户端 $$  int main(int argc, char const *argv[])
{/*创建流式套接字*/int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){perror("socket err");return -1;}else{printf("创建套接字成功\n");}/*指定服务器的网络信息*/struct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(atoi(argv[1]));saddr.sin_addr.s_addr = inet_addr(argv[2]);/* 请求连接服务器*/int t = connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));if (t < 0){perror("connect err");return -1;}else{printf("connect success\n");}char buf[128] = "";/* 发送消息 */while (1){fgets(buf, sizeof(buf), stdin);if (buf[strlen(buf) - 1] == '\n'){buf[strlen(buf) - 1] = '\0';}if (strcmp(buf, "quit") == 0){break;}send(sockfd, buf, sizeof(buf), 0); // 0-->相当于write(sockfd,buf,sizeof(buf))}/* 关闭套接字 */close(sockfd);return 0;
}

5.TCP粘包问题

tcp粘包

tcp拆包

6.三次握手四次挥手

三次握手建立连接

第一次握手:客户通过调用connect进行主动打开(active open)。这引起客户TCP发送一个SYN(表示同步)分节(SYN=J),它告诉服务器客户将在连接中发送数据的初始序列号。并进入SYN_SEND状态,等待服务器的确认。

第二次握手:服务器必须确认客户的SYN,同时自己也得发送一个SYN分节,它含有服务器将在同一连接中发送的数据的初始序列号。服务器以单个字节向客户发送SYN和对客户SYN的ACK(表示确认),此时服务器进入SYN_RECV状态。

第三次握手:客户收到服务器的SYN+ACK。向服务器发送确认分节,此分节发送完毕,客户服务器进入ESTABLISHED状态,完成三次握手。

 

相关文章:

网络编程之TCP编程

基于 C/S &#xff1a;客户端&#xff08;client&#xff09;/服务器端&#xff08;server&#xff09; 1.流程 2. 函数接口 所有函数所需头文件&#xff1a; #include <sys/types.h> #include <sys/socket.h> 系统定义好了用来存储网络信息的结构体 ipv4通信使…...

C++进阶--C++11(04)

文章目录 C进阶--C11&#xff08;04&#xff09;lambdalambda表达式语法捕捉列表lambda的应用lambda的原理 包装器functionbind 总结结语 很高兴和大家见面&#xff0c;给生活加点impetus&#xff01;&#xff01;开启今天的编程之路&#xff01;&#xff01; 今天我们进一步c…...

当AI遇上防火墙:新一代智能安全解决方案全景解析

在2025年网络安全攻防升级的背景下&#xff0c;AI与防火墙的融合正重塑安全防御体系。以下三款产品通过机器学习、行为分析等技术创新&#xff0c;为企业提供智能化主动防护&#xff1a; 1. 保旺达数据安全管控平台——AI驱动的动态治理引擎‌ 智能分类分级‌&#xff1a;基于…...

STL 库基础概念与示例

一、STL 库基础概念与示例 1. 容器分类 顺序容器 核心特性&#xff1a;按元素插入顺序存储&#xff0c;支持下标访问&#xff08;类似数组&#xff09;&#xff0c;动态扩展内存。典型容器&#xff1a;vector&#xff08;动态数组&#xff09;。适用场景&#xff1a;需要频繁…...

Spring MVC参数绑定终极手册:单多参/对象/集合/JSON/文件上传精讲

我们通过浏览器访问不同的路径&#xff0c;就是在发送不同的请求&#xff0c;在发送请求时&#xff0c;可能会带一些参数&#xff0c;本文将介绍了Spring MVC中处理不同请求参数的多种方式 一、传递单个参数 接收单个参数&#xff0c;在Spring MVC中直接用方法中的参数就可以&…...

Fluence推出“Pointless计划”:五种方式参与RWA算力资产新时代

2025年6月1日&#xff0c;去中心化算力平台 Fluence 正式宣布启动“Pointless 计划”——这是其《Fluence Vision 2026》战略中四项核心举措之一&#xff0c;旨在通过贡献驱动的积分体系&#xff0c;激励更广泛的社区参与&#xff0c;为用户带来现实世界资产&#xff08;RWA&am…...

innovus: ecoAddRepeater改变hier层级解决办法

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 来自星球提问: 星主&#xff0c;我在A/B/C/D/E/U0这个cell后面插入一个BUFF&#xff0c;生成的名字为A/B/C/BUFF1&#xff0c;少了D/E两个层级&#xff0c;不应该是生成A/B/C/…...

华为OD机试真题——硬件产品销售方案(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式! 2025华为OD真题目录+全流程解析/备考攻略/经验分享 华为OD机试真题《硬件产品销售方案》: 目录…...

突破数据孤岛:StarRocks联邦查询实战指南

随着企业数据生态的复杂化&#xff0c;跨多个数据存储系统进行联合查询的需求日益增长。本文将深入解析如何利用StarRocks构建高效的数据联邦查询体系&#xff0c;实现与Apache Doris和Hive数据仓库的无缝对接。 ### 一、StarRocks联邦查询架构解析 StarRocks采用分布式架构设…...

传统业务对接AI-AI编程框架-Rasa的业务应用实战(1)--项目背景即学习初衷

我的初衷&#xff1a;我想学习AI。具体的方向是这样的&#xff1a;原本传统的平台业务去对接智能体。比如发票业务&#xff0c;发票的开具、审核、计税、回款等。根据用户在业务系统前台界面输入若干提示词 或者 语音输入简短语音信息&#xff0c;可以通过智能体给出需要处理的…...

低功耗架构突破:STM32H750 与 SD NAND (存储芯片)如何延长手环续航至 14 天

低功耗架构突破&#xff1a;STM32H750 与 SD NAND &#xff08;存储芯片&#xff09;如何延长手环续航至 14 天 卓越性能强化安全高效能效图形处理优势丰富集成特性 模拟模块实时监控保障数据完整性提升安全性与可靠性测量原理采样率相关结束语 在智能皮电手环及数据存储技术不…...

CSS选择子元素

通过选择器 为所有子元素应用样式。以下是几种常见方法&#xff1a; 1. 选择所有直接子元素&#xff08;不包括孙级&#xff09; css 复制 下载 .parent > * {/* 样式规则 */color: red; } > 选择器&#xff1a;只匹配直接子元素 * 通配符&#xff1a;匹配任意类型…...

git cherry-pick (28)

1.1 目的 本文档用于说明如何git上,通过cherry-pick命令合并某个功能。 将分支bg_device的 AHB New feature support libalgo arm64 lib 提交内容合并至 分支spfl_device 分支当中 1.2适配步骤 1.2.1 实操过程 > 分支sfpl_device的状态 rootxrootx-ThinkPad:~/workdir…...

android与Qt类比

一、概念对应关系 Android RecyclerView 组件类比描述Qt 模型 - 视图组件Qt 类比描述RecyclerView画板&#xff08;容器&#xff09;QAbstractItemView视图&#xff08;展示数据的容器&#xff0c;如列表、表格&#xff09;RecyclerView.Adapter画布&#xff08;数据桥梁&…...

AX513CE 是一款针对模组渠道市场前端IPC应用而设计的数字SOC芯片 支持高清CMOS Sensor输入 国产品牌

AX513CE 是一款针对模组渠道市场前端IPC应用而设计的数字SOC芯片 支持高清CMOS Sensor输入 国产品牌 产品概述&#xff1a; AX513CE 是一款针对模组渠道市场前端IPC应用而设计的数字SOC芯片&#xff0c;支持高清CMOS Sensor输入&#xff0c;经ISP处理、视频前处理以及音视频编…...

Linux(11)——基础IO(上)

目录 一、理解文件 二、回顾C文件的接口 &#x1f4c4; C语言文件操作函数表 ​编辑&#x1f4c4; 三个文件流 三、系统文件I/O 1️⃣open 2️⃣close 3️⃣write 4️⃣read 四、文件描述符 &#x1f4a1;用户操作文件的底层逻辑是什么&#xff1f; &#x1f4…...

ABP-Book Store Application中文讲解 - Part 9: Authors: User Interface

ABP-Book Store Application中文讲解 - Part 9: Authors: User Interface TBD 1. 汇总 ABP-Book Store Application中文讲解-汇总-CSDN博客 2. 前一章 ABP-Book Store Application中文讲解 - Part 8: Authors: Application Layer-CSDN博客 项目之间的引用关系。 ​​ 目…...

鸿蒙开发修改版本几个步骤

鸿蒙开发修改版本几个步骤 比如&#xff1a;5.0.4&#xff08;16&#xff09;版本改为5.0.2&#xff08;14&#xff09;版本 一、项目下的build-profile.json5 "products": [{"name": "default","signingConfig": "default&qu…...

Hive自定义函数案例(UDF、UDAF、UDTF)

目录 前提条件 背景 概念及适用场景 UDF&#xff08;User-Defined Function&#xff09; 概念 适用场景 UDAF&#xff08;User-Defined Aggregate Function&#xff09; 概念 适用场景 UDTF&#xff08;User-Defined Table-Generating Function&#xff09; 概念 适…...

【学习笔记】Circuit Tracing: Revealing Computational Graphs in Language Models

Circuit Tracing: Revealing Computational Graphs in Language Models 替代模型(Replacement Model)&#xff1a;用更多的可解释的特征来替代transformer模型的神经元。 归因图(Attribution Graph)&#xff1a;展示特征之间的相互影响&#xff0c;能够追踪模型生成输出时所采用…...

3D视觉重构工业智造:解码迁移科技如何用“硬核之眼“重塑生产节拍

一、工业视觉的进化论&#xff1a;从CCD到3D相机的范式革命 在汽车冲压车间里&#xff0c;传统CCD相机正面临四大检测困局&#xff1a; 平面感知局限&#xff1a;二维视觉无法捕捉曲面工件形变环境适应性差&#xff1a;反光板件导致误检率超12%动态捕捉延迟&#xff1a;传送带…...

Elasticsearch中的刷新(Refresh)和刷新间隔介绍

在 Elasticsearch 中,刷新(Refresh) 是控制索引数据何时对搜索可见的机制,而 刷新间隔(Refresh Interval) 则是配置该机制执行频率的参数。理解这两个概念对于平衡搜索实时性与写入性能至关重要。 一、刷新(Refresh)的本质 Lucene 索引结构与搜索可见性Elasticsearch …...

STM32标准库-TIM定时器

文章目录 一、TIM定时器1.1定时器1.2定时器类型1.1.1 高级定时器1.1.2通用定时器1.1.3基本定时器 二、定时中断基本结构预分频器时器计时器时序计数器无预装时序计数器有预装时序RCC时钟树 三、定时器定时中断3.1 接线图3.2代码3.3效果&#xff1a; 四、定时器外部中断4.1接线图…...

【算法训练营Day05】哈希表part1

文章目录 哈希表理论基础有效的字母异位词两个数组的交集快乐数两数之和 哈希表理论基础 几个值得关注的知识点&#xff1a; hash表用于快速的判断元素是否存在&#xff08;空间换时间&#xff09;其原理就是将数据通过散列函数映射到bucket中&#xff0c;如果发生hash碰撞&a…...

CMap应用场景和例子

CMap 详解 CMap 是 MFC (Microsoft Foundation Classes) 库中的一个模板类&#xff0c;用于实现键值对的映射关系&#xff08;类似哈希表或字典&#xff09;。它提供了高效的数据存储和检索功能&#xff0c;适用于需要通过键快速查找值的场景。 基本模板参数 cpp 运行 tem…...

Kafka 如何保证顺序消费

在消息队列的应用场景中&#xff0c;保证消息的顺序消费对于一些业务至关重要&#xff0c;例如金融交易中的订单处理、电商系统的库存变更等。Kafka 作为高性能的分布式消息队列系统&#xff0c;通过巧妙的设计和配置&#xff0c;能够实现消息的顺序消费。接下来&#xff0c;我…...

【算法题】算法一本通

每周更新至完结&#xff0c;建议关注收藏点赞。 目录 待整理文章已整理的文章方法论思想总结模版工具总结排序 数组与哈希表栈双指针&#xff08;滑动窗口、二分查找、链表&#xff09;树前缀树堆 优先队列&#xff08;区间/间隔问题、贪心 &#xff09;回溯图一维DP位操作数学…...

Modbus转Ethernet IP赋能挤出吹塑机智能监控

在现代工业自动化领域&#xff0c;小疆智控Modbus转Ethernet IP网关GW-EIP-001与挤出吹塑机的应用越来越广泛。这篇文章将为您详细解读这两者的结合是如何提高生产效率&#xff0c;降低维护成本的。首先了解什么是Modbus和Ethernet IP。Modbus是一种串行通信协议&#xff0c;它…...

C++中如何遍历map?

文章目录 1. 使用范围for循环&#xff08;C11及以上&#xff09;2. 使用迭代器3. 使用反向迭代器注意事项 在C中&#xff0c; std::map 是一种关联容器&#xff0c;它存储的是键值对&#xff08;key-value pairs&#xff09;&#xff0c;并且按键的顺序进行排序。遍历 std::m…...

什么是终端安全管理系统(终端安全管理软件2024科普)

在当今数字化迅速发展的时代&#xff0c;企业面临着越来越多的信息安全威胁。为了应对这些挑战&#xff0c;保障公司数据的安全性和完整性&#xff0c;终端安全管理系统&#xff08;Endpoint Security Management System&#xff09;应运而生。 本文将为您深入浅出地科普2024年…...