Socket通信详解
Socket通信详解
文章目录
- Socket通信详解
- Socket流程介绍
- 函数介绍
- 编程实例
 
Socket流程介绍
socket通信类似于电话通信,其服务器基本流程就是
函数介绍
- socket()
其中socket的函数原型如下所示,它的作用就是创建套接字,同时规定好该套接字的用途

其中的每个参数的作用如下所示:
domain:套接字使用的协议族信息(比如PF_INET就是使用IVP4互联网协议族)
type:套接字数据传输类型信息(比如SOCK_STREAM是指面向连接的套接字类型,TCP就是这个类型)
protocol:计算机通信中使用的协议信息(比如IPV4,面向连接类型,基本就只有TCP,这里就填写IPPROTO_TCP)
- bind()
其中bind的函数原型如下所示,它的作用就是把地址信息分配给套接字上,也就是前面socket生成的套接字上。其函数原型如下所示:

其中中间的__CONST_SOCKADDR_ARG是个宏,继续追踪可以知道是个存储地址信息的结构体,如下所示

其中每个参数的作用如下所示:
fd:套接字描述符,就是前文socket函数的返回值,结构体信息是绑定在这个套接字上的
addr:存储地址信息的指针,里面有IP和端口信息。
len:就是第二个参数addr的长度
那么addr里面的具体详情又是怎么样的呢,即sockaddr的结构体定义如下所示,是一个14个字节长度的字符串数组。

为了便于填写,我们一般使用sockaddr_in结构体,然后进行强制类型转换为sockaddr类型,

上图中的name就是sockaddr_in类型,sockadr_in结构体类型如下所示:

第一个红框中的变量为sin_family,其演变如下所示

对socket_In结构体的变量解析如下
sin_family:地址族(比如IPV4就填写AF_INET)
sin_port:填写16位网络端口,重点是它是以网络字节序保存,所以需要进行转换
sin_addr:填写32为ip地址,也以网络字节序保存。
sin_zero:无实际含义,为了保持与socket结构体长度一致,方便强制类型转换。
- listen()
其中listen的函数原型如下所示

其参数解析如下
fd:前面两个函数都用到过的套接字描述符
n:表示连接请求队列的长度,如果设置为5,则队列长度为5,表示最多使五个连接请求进入队列
- accept()
其中accept()的函数原型如下所示

其参数解析如下
fd:服务器的套接字描述符
addr:用来保存发起连接的客户端的地址信息
addr_len:第二个参数的结构体长度,当函数调用完成后,这个参数就是被填入的客户端地址长度
返回值:一个套接字的文件描述符,这个套接字是accept函数生成的用来和这个客户端对话的。
编程实例
-  文件介绍 hello_server.c就是主要的文件,也就是实例。hello_client.c是配合服务器测试的客户端程序。Makefile是用来编译两者的。
-  测试流程 make ./hello_server 9190 //这个端口随便选择一个没有占用的端口即可 ./hello_client 127.0.0.1 9190//这里的ip和端口号要与服务器的ip端口号保持一致此时客户端会收到一个消息,消息内容为 Message from server: hello World!
-  测试截图 服务端运行 

客户端运行以及结果

-  hello_server.c #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <unistd.h> void error_handling(char* message); int main(int argc, char* argv[]) {int serv_sock;int clnt_sock;struct sockaddr_in serv_addr;struct sockaddr_in clnt_addr;socklen_t clnt_addr_size;char message[] = "hello World!";if (argc != 2) {printf("Usage : %s <port>\n", argv[0]);exit(1);}serv_sock = socket(PF_INET, SOCK_STREAM, 0);//创建套接字if (serv_sock == -1) {error_handling("socket() error");}memset(&serv_addr, 0, sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);serv_addr.sin_port = htons(atoi(argv[1]));if (bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)//将地址信息绑定套接字error_handling("bind() error");if (listen(serv_sock, 5) == -1) error_handling("listen() error");//监听套接字clnt_addr_size = sizeof(clnt_addr);clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);//当收到客户端消息的时候创建一个套接字来进行通信if (clnt_sock == -1) {error_handling("accept() error");}write(clnt_sock, message, sizeof(message));close(clnt_sock);close(serv_sock);return 0; } void error_handling(char* message) {fputs(message, stderr);fputc('\n', stderr);exit(1); }
-  hello_client.c #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <unistd.h> void error_handling(char* message); int main(int argc, char* argv[]) {int sock;struct sockaddr_in serv_addr;char message[30];int str_len;if (argc != 3) {printf("Usage : %s <IP> <port>\n", argv[0]);exit(1);}sock = socket(PF_INET, SOCK_STREAM, 0);if (sock == -1) {error_handling("socket() error");}memset(&serv_addr, 0, sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = inet_addr(argv[1]);serv_addr.sin_port = htons(atoi(argv[2]));if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)error_handling("connect() error");str_len = read(sock, message, sizeof(message) - 1);if (str_len == -1) error_handling("read() error");printf("Message from server: %s \n", message);close(sock);return 0; } void error_handling(char* message) {fputs(message, stderr);fputc('\n', stderr);exit(1); }
-  MakeFile all: server clientserver: hello_server.cclang-format -style=google -i hello_server.cgcc hello_server.c -o hello_server client: hello_client.cclang-format -style=google -i hello_client.cgcc hello_client.c -o hello_client clean:rm hello_client hello_server
相关文章:
 
Socket通信详解
Socket通信详解 文章目录Socket通信详解Socket流程介绍函数介绍编程实例Socket流程介绍 socket通信类似于电话通信,其服务器基本流程就是 Created with Raphal 2.3.0安装电话socket()分配电话号码bind()连接电话线listen()拿起话筒accept()函数介绍 socket() 其中…...
 
多分类、正则化问题
多分类问题 利用逻辑回归解决多分类问题,假如有一个训练集,有 3 个类别,分别为三角形 𝑦 1,方框𝑦 2,圆圈 𝑦 3。我们下面要做的就是使用一个训练集,将其分成 3 个二…...
 
史上最全面的软件测试面试题总结(接口、自动化、性能全都有)
目录 思维发散 Linux 测试概念和模型 测试计划与工具 测试用例设计 Web项目 Python基础 算法 逻辑 接口测试 性能测试 总结感谢每一个认真阅读我文章的人!!! 重点:配套学习资料和视频教学 思维发散 一个球ÿ…...
 
速来~与 Werner Vogels 博士一起探索敏捷性与创新速度一起提升的秘方
Amazon Web Services 的现代应用程序创新一直是 Amazon 公司坚持追求的核心目标。约20年前,我们经历了一次彻底的转型,旨在建立起“发明、发布、再发明、再发布、重新开始、洗牌、再重复”的快速迭代流程。正是此番探索,彻底改变了我们构建应…...
 
Apache Hadoop、HDFS介绍
目录Hadoop介绍Hadoop集群HDFS分布式文件系统基础文件系统与分布式文件系统HDFS简介HDFS shell命令行HDFS工作流程与机制HDFS集群角色与职责HDFS写数据流程(上传文件)HDFS读数据流程(下载文件)Hadoop介绍 用Java语言实现开源 允许…...
 
python“r e 模块“常见函数详解
正则表达式:英文Regular Expression,是计算机科学的一个重要概念,她使用一种数学算法来解决计算机程序中的文本检索,匹配等问题,正则表达式语言是一种专门用于字符串处理的语言。在很多语言中都提供了对它的支持,re模块…...
 
【数据结构】二叉树的四种遍历方式——必做题
写在前面学完上一篇文章的二叉树的遍历之后,来尝试下面的习题吧开始做题144. 二叉树的前序遍历 - 力扣(LeetCode)94. 二叉树的中序遍历 - 力扣(LeetCode)145. 二叉树的后序遍历 - 力扣(LeetCode)…...
Nginx使用“逻辑与”配置origin限制,修复CORS跨域漏洞
目录1.漏洞报告2.漏洞复现3.Nginx 修复3.1 添加请求头3.2 配置origin限制2.3 调整origin限制1.漏洞报告 漏洞名称: CORS 跨域漏洞等级: 中危漏洞证明: Origin从任何域名都可成功访问,未做任何限制。漏洞危害: 因为同源…...
 
Laravel框架02:路由与控制器
Laravel框架02:路由与控制器一、路由配置文件二、路由参数三、路由别名四、路由群组五、控制器概述六、控制器路由七、接收用户输入一、路由配置文件 以web网页路由文件为例: 默认根路由 路由定义格式Route::请求方式(请求的URL, 匿名函数或控制响应的方…...
【POJ 2418】Hardwood Species 题解(映射)
描述 阔叶树是一种植物群,具有宽阔的叶子,结出果实或坚果,通常在冬天休眠。 美国的温带气候造就了数百种阔叶树种的森林,这些树种具有某些生物特征。例如,虽然橡树、枫树和樱桃都是硬木树,但它们是不同的物…...
React组件之间的通信方式总结(下)
一、写一个时钟 用 react 写一个每秒都可以更新一次的时钟 import React from react import ReactDOM from react-domfunction tick() {let ele <h1>{ new Date().toLocaleTimeString() }</h1>// Objects are not valid as a React child (found: Sun Aug 04 20…...
 
【RabbitMQ笔记07】消息队列RabbitMQ七种模式之Publisher Confirms发布确认模式
这篇文章,主要接收消息队列RabbitMQ七种模式之Publisher Confirms发布确认模式。 目录 一、消息队列 1.1、发布确认模式 1.2、案例代码 (1)引入依赖 (2)编写生产者【消息确认--单条确认】 (3…...
 
【华为OD机试模拟题】用 C++ 实现 - IPv4 地址转换成整数(2023.Q1)
最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 去重求和(2023.Q1) 文章目录 最近更新的博客使用说明IPv4 地址转换成整数题目输入输出示例一输入输出说明示例一输入输出说明Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,...
闭包与高阶函数
文中内容均来自于曾探《JavaScript设计模式与开发实践》的学习笔记。闭包作用域变量的作用域,就是指变量的有效范围。局部变量、全局变量。变量的搜索是从内到外而非从外到内的。变量的生命周期对于全局变量莱索,全局变量的生命周期是永久的,…...
 
人工智能轨道交通行业周刊-第35期(2023.2.20-2.26)
本期关键词:重庆智慧轨道、智能运维主机、标准轨距、地方铁路公报、景深、机器视觉应用 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通Rai…...
快慢指针判断链表是否有环
快慢指针判断链表是否有环 单链表有可能存在环,有些情况下要判断一个单链表是否有环。数组的有个快慢指针的方法,其实单链表和数组有相似的地方,可以使用快慢指针的方法。具体做法如下: 首先创建两个指针,它们初始时…...
《MongoDB入门教程》第26篇 聚合统计之$max/$min表达式
本文将会介绍两个 MongoDB 表达式,返回一组数据中最大值的 $max 表达式,以及返回一组数据中最小值的 $min 表达式。 $max 表达式 $max 表达式用于返回一组数据中的最大值,语法如下: { $max: <expression> }$max 表达式在…...
 
FPGA纯verilog解码SDI视频 纯逻辑资源实现 提供2套工程源码和技术支持
目录1、前言2、硬件电路解析SDI摄像头Gv8601a单端转差GTX解串SDI解码VGA时序恢复YUV转RGB图像输出FDMA图像缓存HDMI输出3、工程1详解:无缓存输出4、工程2详解:缓存3帧输出5、上板调试验证并演示6、福利:工程代码的获取1、前言 FPGA实现SDI视…...
 
JVM篇之垃圾回收
一.如何判断对象可以回收 1.引用计数法 只要一个对象被其他变量所引用,就让它的计数加1,被引用了两次就让它的计数变成2,当这个变量的计数变成0时,就可以被垃圾回收; 弊端:当出现如下图的情况࿰…...
 
尝试用程序计算Π(3.141592653......)
文章目录1. π\piπ2. 用微积分来计算π\piπ2.1 原理2.2 代码2.3 结果2.4 分析1. π\piπ π\piπ的重要性或者地位不用多说,有时候还是很好奇,精确地π\piπ值是怎么计算出来的。研究π\piπ的精确计算应该是很多数学家计算机科学家努力的方向…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
 
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
 
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
 
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
 
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
 
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
 
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
 
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
