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天的回款周期,这对于商家的周转来说是一件很困难的事情,在供应链金融中,分账就扮演着至关重要的角色,不仅是金融流程中的一环,更是保…...
【测绘程序设计】——坐标换带与高程投影
测绘工程中经常遇到 “坐标换带” 与 “高程投影” 问题,前者是在改变投影的分带号——即投影的中央子午线,通过 “(x,y)->(B,L)->(x,y)” 进行;而后者则是为减小投影变形(高程投影变短、高斯投影变长,详情可参考博客《测绘综合能力》真题易错本 第(37)条)通过平…...
企业计算机服务器中了Mallox勒索病毒如何解密,Mallox勒索病毒数据恢复
随着计算机技术的不断应用与发展,网络为企业的生产运营提供了极大帮助,越来越多的企业开始利用网络办公,因此,随之而来的网络安全威胁也在不断增加。近期,云天数据恢复中心陆续接到很多企业的求助,企业的计…...
一套rk3588 rtsp服务器推流的 github 方案及记录 -01
我不生产代码,我只是代码的搬运工,相信我,看完这个文章你的图片一定能变成流媒体推出去。 诉求:使用opencv拉流,转成bgr数据,需要把处理后的数据(BGR)编码成264,然后推流…...
PyQt6 QComboBox下拉组合框控件
锋哥原创的PyQt6视频教程: 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计34条视频,包括:2024版 PyQt6 Python桌面开发 视频教程(无废话…...
常用类与比较器
常用类 学一个类,先搞清楚继承关系,再看源码 包装类Wrapper jdk5之前是手动装箱拆箱 jdk5及之后是自动装箱拆箱(调用valueOf方法(自动默认)/创建对象的构造方法,XXXvalue方法…...
【上海大学《面向对象程序设计A》课程小项目报告】抽象向量类模板及其派生类
1 项目内容及要求 本项目通过设计一个抽象向量类模板,以及一个通用的向量类模板和一个字符串类作为其派生类,以满足各种应用场景中的数据存储和处理需求。 项目内容: 抽象向量类模板。派生向量类。派生字符串类。测试及异常处理。联合测试…...
Leetcode每日一题学习训练——Python3版(到达首都的最少油耗)
版本说明 当前版本号[20231205]。 版本修改说明20231205初版 目录 文章目录 版本说明目录到达首都的最少油耗理解题目代码思路参考代码 原题可以点击此 2477. 到达首都的最少油耗 前去练习。 到达首都的最少油耗 给你一棵 n 个节点的树(一个无向、连通、无环…...
Java面试题(每天10题)-------连载(42)
目录 Spring篇 1、Spring Bean的作用域之间有什么区别? 2、什么是Spring inner beans? 3、Spring框架中的单例Beans是线程安全的吗? 4、请举例说明如何在Spring中诸如一个Java Collection? 5、如何向Spring Bean中诸如一个J…...
netty websocket学习
【硬核】肝了一月的Netty知识点 超详细Netty入门,看这篇就够了! bzm_netty_sb netty-chat vuewebsokect实现实时聊天,可单聊、可群聊(一) vue实现聊天栏定位到最底部(超简单、可直接复制使用)…...
【数据结构】环形队列
环形队列 1. 定义 环形队列就是将队列在逻辑上看作环形结构、物理上仍是数组形式存储的一种数据结构。 其实现主要分为两种情况: 浪费空间法记录空间法 2. 实现 实现要考虑的是成员变量 2.1 记录空间法 使用used标识当前存储了多少元素,如果为空&a…...
一个做二维码问卷调查的网站/百度竞价排名怎么做
本文主要解决openssl升级到1.1.0以上版本,导致shadows2.8.2启动报undefined symbol: EVP_CIPHER_CTX_cleanup错误。 如果在安装完Shadows后,启动时报 AttributeError: /usr/local/ssl/lib/libcrypto.so.1.1: undefined symbol: EVP_CIPHER_CTX_cleanup…...
网站的交互体验/搜索引擎优化的目的是对用户友好
上海工程技术大学C语言考试试卷一、选择题(本题共15小题,每小题2分,共30分)1.下列字符串能作为变量名的是()A)3int B)float C)_2xy D)break2.以下选项中可作为C语言合法整数的是(A)1010B B)0287 C)0x02h3 D)0x0ffa3.下列正确的C语句是(A)x2 B)scanf(“%d…...
馆陶企业做网站推广/关键词排名优化易下拉技巧
1、启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取<listener>和<context-param>两个结点。 2、紧急着,容创建一个ServletContext(servlet上下文),这个web项目的所有部分都将…...
做百度网站需要什么条件/视频营销模式有哪些
声明:此篇文章是个人学习笔记,并非教程,所以内容可能不够严谨。可作参考,但不保证绝对正确。如果你发现我的文章有什么错误,非常欢迎指正,谢谢哦 OnMouseEnter、OnMouseOver、OnMouseExit这三个函数类似于…...
湖南网站开发/网络推广外包流程
最近在做的项目有一项需要耗时任务在后台运行的功能,虽然PHP并不是非常适合做常驻后台的守护进程,但是由于项目主要代码都是基于PHP实现,如果运行在后台的守护进程改换别的语言会非常不方便。所以不可避免会涉及到Web端和Daemon部分的通信&am…...
如何快速自己做网站/网络销售怎么聊客户
转载至:http://blog.csdn.net/denglxsc/article/details/51188444 在开发过程中对程序方法、类的描述不仅方便阅读、更能体现一个良好的编码习惯,但是自带的文档注释快捷键以及自动生成的注释总是不够完美,既然不完美,那么我们就…...