102.套接字-Socket网络编程4(TCP通信流程)
目录
TCP编程流程
套接字函数
1.创建套接字
2.绑定地址
3.监听连接请求
4.接受连接
5. 连接到服务器
6. 发送数据
7. 接收数据
8.关闭套接字
服务器端通信流程
示例代码
客户端通信流程
代码示例
TCP编程流程
TCP是一个面向连接的,安全的,流式传输协议,这个协议是一个传输层协议。
- 面向连接:是一个双向连接,通过三次握手完成,断开连接需要通过四次挥手完成。
- 安全:tcp通信过程中,会对发送的每一数据包都会进行校验, 如果发现数据丢失, 会自动重传
- 流式传输:发送端和接收端处理数据的速度,数据的量都可以不一致。
TCP 的服务器端和客户端编程流程如下:
套接字函数
套接字编程中,常用的套接字函数通常涵盖套接字的创建、绑定、监听、连接、发送、接收、关闭等操作。以下是一些常用的套接字函数,这些函数通常在C语言的
<sys/socket.h>
头文件中声明:1.创建套接字
int socket(int domain, int type, int protocol);
参数:
domain
:使用的地址协议族,如AF_INET、AF_INET6分别
表示IPv4、IPv6格式。type
:套接字类型,如 SOCK_STREAM(流式传输协议)
表示TCP套接字,SOCK_DGRAM(报式传输协议)表示UDP套接字。protocol
:通常为0,表示自动选择协议。返回值:
- 成功:返回新创建套接字的文件描述符。
- 失败:返回-1,并设置
errno
。2.绑定地址
// 将文件描述符和本地的IP与端口进行绑定 int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数:
sockfd
:套接字的文件描述符,通过socket调用得到的返回值。addr
:包含要绑定的IP地址和端口号的结构体。addrlen
:addr
结构体的大小,sizeof(addr)。返回值:
- 成功:0,失败:返回-1。
3.监听连接请求
// 给监听的套接字设置监听 int listen(int sockfd, int backlog);
参数:
sockfd
:套接字的文件描述符,通过socket调用得到的返回值。backlog
:在进入队列中等待接受的最大连接数,最大值为128。返回值:
- 成功:0,失败:返回-1。
4.接受连接
// 等待并接受客户端的连接请求, 建立新的连接, 会得到一个新的文件描述符(通信的) int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数:
sockfd
:套接字的文件描述符。addr
:用于存储客户端地址信息的结构体。addrlen
:addr
结构体的大小。返回值:
- 函数调用成功,得到一个文件描述符, 用于和建立连接的这个客户端通信,调用失败返回 -1。
这个函数是一个阻塞函数,当没有新的客户端连接请求的时候,该函数阻塞;当检测到有新的客户端连接请求时,阻塞解除,新连接就建立了,得到的返回值也是一个文件描述符,基于这个文件描述符就可以和客户端通信了。
5. 连接到服务器
// 成功连接服务器之后, 客户端会自动随机绑定一个端口 // 服务器端调用accept()的函数, 第二个参数存储的就是客户端的IP和端口信息 int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数:
sockfd
:套接字的文件描述符,通过socket调用得到的返回值。addr
:用于存储客户端地址信息的结构体,这个IP和端口也需要转换为大端然后再赋值。addrlen
:addr
结构体的大小。返回值:
- 连接成功返回0,连接失败返回-1
6. 发送数据
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
参数:
sockfd
:套接字的文件描述符。buf
:包含要发送数据的缓冲区。len
:要发送的数据的长度。flags
:发送标志,通常为0。返回值:
- 成功:返回发送的字节数。
- 失败:返回-1。
7. 接收数据
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
参数:
sockfd
:套接字的文件描述符。buf
:用于接收数据的缓冲区。len
:要接收的数据的长度。flags
:接收标志,通常为0。返回值:
- 成功:返回接收的字节数。
- 失败:返回-1。
8.关闭套接字
int close(int sockfd);
参数:
sockfd
:套接字的文件描述符。返回值:
- 成功:0,失败:返回-1。
服务器端通信流程
1.创建套接字: 使用
socket
函数创建一个套接字,指定协议族(通常是AF_INET
表示IPv4)、套接字类型(SOCK_STREAM
表示TCP流套接字)、协议(通常为0,表示自动选择协议)。int server_socket = socket(AF_INET, SOCK_STREAM, 0);
2.绑定地址: 使用
bind
函数将套接字与特定的IP地址和端口号绑定。struct sockaddr_in server_address; server_address.sin_family = AF_INET; server_address.sin_port = htons(8888); server_address.sin_addr.s_addr = INADDR_ANY;bind(server_socket, (struct sockaddr *)&server_address, sizeof(server_address));
3.监听连接请求: 使用
listen
函数开始监听连接请求。listen(server_socket, 5); // 允许最多5个连接请求排队
4.接受连接: 使用
accept
函数接受客户端的连接请求,该函数会阻塞程序直到有客户端连接进来。int client_socket = accept(server_socket, NULL, NULL);
5.进行数据交互: 使用
send
和recv
函数进行数据的发送和接收。char buffer[1024]; recv(client_socket, buffer, sizeof(buffer), 0); send(client_socket, "Hello from server", strlen("Hello from server"), 0);
6.关闭套接字: 使用
close
函数关闭服务端的套接字。close(server_socket);
示例代码
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h>int main() {// 1.创建监听的套接字int fd = socket(AF_INET, SOCK_STREAM, 0);if (fd == -1){perror("socket");return -1;}// 2.绑定本地的IP portstruct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(9999);saddr.sin_addr.s_addr = INADDR_ANY; // INADD_ANY自动读取本地的ip地址int ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));if (ret == -1){perror("bind");return -1;}// 3.设置监听ret = listen(fd, 128);if (ret == -1){perror("listen");return -1;}// 4.阻塞并等待客户端的连接struct sockaddr_in caddr;int addrlen = sizeof(caddr);int cfd = accept(fd, (struct sockaddr *)&caddr, &addrlen);if (cfd == -1){perror("accept");return -1;}// 连接建立成功,打印客户端的ip和端口信息char ip[32];printf("客户端的ip:%s,端口:%d\n", inet_ntop(AF_INET, &caddr.sin_addr.s_addr, ip, sizeof(ip)), ntohs(caddr.sin_port));// 5.通信while (1){ // 接受数据char buff[1024];int len = recv(cfd, buff, sizeof(buff), 0);if (len > 0){printf("client say:%s\n", buff);send(cfd, buff, len, 0);}else if (len == 0){printf("客户端已经断开了连接...\n");break;}else{perror("recv");break;}}close(fd);return 0; }
客户端通信流程
1.创建套接字: 使用
socket
函数创建一个套接字。int client_socket = socket(AF_INET, SOCK_STREAM, 0);
2.设置服务器地址: 设置服务器的地址信息,包括协议族、IP地址和端口号。
struct sockaddr_in server_address; server_address.sin_family = AF_INET; server_address.sin_port = htons(8888); server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
3.连接服务器: 使用
connect
函数连接到服务器。connect(client_socket, (struct sockaddr *)&server_address, sizeof(server_address));
4.进行数据交互: 使用
send
和recv
函数进行数据的发送和接收。char buffer[1024]; send(client_socket, "Hello from client", strlen("Hello from client"), 0); recv(client_socket, buffer, sizeof(buffer), 0);
5.关闭套接字: 使用
close
函数关闭客户端的套接字。close(client_socket);
代码示例
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h>int main() {// 1.创建通信的套接字int fd = socket(AF_INET, SOCK_STREAM, 0);if (fd == -1){perror("socket");return -1;}// 2.连接服务器的IP portstruct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(9999);inet_pton(AF_INET, "192.168.3.128", &saddr.sin_addr.s_addr);int ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));if (ret == -1){perror("connect");return -1;}int number = 0;// 3.通信while (1){ // 发送数据char buff[1024];sprintf(buff, "你好,hello,world,%d...\n", number++);send(fd, buff, sizeof(buff), 0);// 接收数据memset(buff, 0, sizeof(buff));int len = recv(fd, buff, sizeof(buff), 0);if (len > 0){printf("server say:%s\n", buff);}else if (len == 0){printf("服务器端已经断开了连接...\n");break;}else{perror("recv");break;}sleep(1);}// 关闭文件描述符close(fd);return 0; }
相关文章:

102.套接字-Socket网络编程4(TCP通信流程)
目录 TCP编程流程 套接字函数 1.创建套接字 2.绑定地址 3.监听连接请求 4.接受连接 5. 连接到服务器 6. 发送数据 7. 接收数据 8.关闭套接字 服务器端通信流程 示例代码 客户端通信流程 代码示例 TCP编程流程 TCP是一个面向连接的,安全的,流…...

spring boot 2 升级到 spring boot 3 后文件上传失败
背景 项目需要,要求升级 spring boot 2.7 到 spring boot 3.2,升级过程中发现很多不兼容问题,下面说明文件上传失败的解决方案。 问题 spring boot 2 中不需要额外的配置,直接在 Controller 中配置 MultipartFile 接收页面传的…...
Java Stream API 提供了一种非常方便的方式来比较两个 List 的差异,并取出不同的对象
Java Stream API 提供了一种非常方便的方式来比较两个 List 的差异,并取出不同的对象。这可以通过使用 distinct() 和 filter() 方法来实现。 假设我们有两个 List,一个是 list1,另一个是 list2,我们想找出 list1 中存在但 list2…...
C语言还会存在多久
一、C语言的生命力 在当前的科技发展和就业市场需求下,可以肯定地说C语言并没有像一些新兴语言(如Python、JavaScript等)那样受到大量的关注。然而,并不意味着学习C语言的人会越来越少。 首先,C语言作为一种深受尊重…...

手持式安卓主板_PDA安卓板_智能手持终端方案
手持式安卓主板方案是一种智能终端设备,具备自动对焦和闪光灯功能,可以在昏暗的环境下快速扫描二维码并轻松采集数据。该方案还提供多渠道支付和数据采集功能,为用户提供了便捷的体验。 该方案的产品基于手持式安卓主板,并搭载了八…...
LeetCode103. Binary Tree Zigzag Level Order Traversal
文章目录 一、题目二、题解 一、题目 Given the root of a binary tree, return the zigzag level order traversal of its nodes’ values. (i.e., from left to right, then right to left for the next level and alternate between). Example 1: Input: root [3,9,20,n…...
PHP 判断给定两个时间是否在同一周,月,年
判断是否在同一周 date_default_timezone_set(PRC); //判断是否在同一周,原理:求出其中一个时间戳所在周的周一凌晨时间戳和周日24.00时间戳,如果另一个时间戳在这个范围内,则说明在同一周,否则不在同一周 function g…...

单机无锁线程安全队列-Disruptor
Disruptor 1、基本介绍 说到队列,除了常见的mq中间件,java中也自带线程安全的BlockingQueue,但是BlockingQueue通过在入队和出队时加锁的方式避免并发操作,性能上会大打折扣。 而Disruptor是一个线程安全、低延迟、吞吐量高的队…...
好工具知多少:国内外最常用的SCADA软件
随着现代SCADA系统的发展,工业自动化取得了巨大的飞跃。如今,监控和数据采集(SCADA)系统已成为工业过程的重要组成部分。这些系统使操作员能够实时监控和控制复杂的系统。 SCADA系统正在广泛的行业中发挥着至关重要的作用&#x…...

SQL Server 2016(创建数据库)
1、实验环境。 某公司有一台已经安装了SQL Server 2016的服务器,现在需要新建数据库。 2、需求描述。 创建一个名为"db_class"的数据库,数据文件和日志文件初始大小设置为10MB,启用自动增长,数据库文件存放路径为C:\db…...
Vue学习计划--Vue2(一)简单了解vue
Vue2的终止支持时间为2023年12月31日。 在这个矛盾的时间点,还是决定先把vue2的笔记放出来,在Vue2完结后再把Vue3的笔记补上。这样呢,2和3都不落下,也算是来一个启承的作用吧。在工作中呢,旧的项目可以维护,…...

微信小程序生成二维码并保存到本地方法
微信小程序生成二维码请保存到本地方法 官方weapp-qrcode插件 github链接 功能完成样子 wxml <view class"qrcode"><canvas style"width: 275px; height: 275px;" canvas-idmyQrcode></canvas> </view> <view class" …...
shell_exec 和 exec区别
shell_exec 和 exec 都是用于在 PHP 中执行系统命令的函数,但它们之间有一些区别。 返回值类型:shell_exec 函数返回命令的输出结果作为字符串,而 exec 函数将输出结果存储在数组中。 输出结果:shell_exec 函数返回命令的完整输出…...

WPF创建进度条
使用wpf做一个原生的进度条,进度条上面有值,先看效果。 功能就是点击按钮,后台处理数据,前台显示处理数据的变化,当然还可以对进度条进行美化和关闭的操作,等待后台处理完毕数据,然后自动关闭。…...

全网最新最全面的Appium自动化:Appium常用操作之混合应用webview页面操作--待补充!
上下文操作: 在appium中,对于混合应用,需要进行WebView页面和原生应用的切换 常用的方法如下: 1、context(self) / current_context(self):返回当前会话的当前上下文,context可以理解为可进入的窗口。对于…...

基于OpenCV+YOLOv5实现车辆跟踪与计数(附源码)
导 读 本文主要介绍基于OpenCVYOLOv5实现车辆跟踪与计数的应用,并给出源码。 资源下载 基础代码和视频下载地址: https://github.com/freedomwebtech/win11vehiclecount main.py代码: import cv2import torchimport numpy as npfrom tr…...

05、pytest断言确定的异常
官方用例 # content of test_sysexit.py import pytestdef f():raise SystemExit(1)def test_mytest():with pytest.raises(SystemExit):f()解读与实操 标准python raise函数可产生异常。pytest.raises可以断言某个异常会发现。异常发生了,用例执行成功&#x…...

金蝶云星空单据编辑界面,不允许批量填充操作
文章目录 金蝶云星空单据编辑界面,不允许批量填充操作案例演示开发设计测试 金蝶云星空单据编辑界面,不允许批量填充操作 案例演示 售后单,明细信息单据体,物料编码字段禁止批量填充。 开发设计 编写表单插件,在Be…...
Springboot项目启动成功后可通过五种方式继续执行
实现CommandLineRunner接口 项目初始化完毕后,才会调用方法,提供服务 Component public class StartRunner implements CommandLineRunner {Overridepublic void run(String... args) throws Exception {System.out.println("CommandLineRunner&qu…...
什么是供应链金融分账系统?
一、供应链金融的重要性 供应链金融在很多行业都是要用到,比如在抖音,快手店铺的商家资金回笼,通常需要7-21天的回款周期,这对于商家的周转来说是一件很困难的事情,在供应链金融中,分账就扮演着至关重要的角色,不仅是金融流程中的一环,更是保…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...