【网络】Socket编程
文章目录
- 正确理解端口号
- 理解源IP地址和目的IP地址
- 认识端口号
- 端口号和进程ID
- 理解Socket
- 网络字节序
- socket编程接口
- 创建socket套接字
- bind绑定套接字
- listen建立监听
- accept接受连接
- connect建立连接
- sendto发送数据
- 接收数据
- close关闭套接字
- sockaddr结构体
正确理解端口号
理解源IP地址和目的IP地址
我们知道通过IP地址我们能在网络中唯一标识一台主机,这也就意味着,只要我知道你的IP地址,就能向你的主机发送数据。但是这有一个问题,主机接收到数据之后发送给哪个进程呢?也就是说,光靠IP地址我们只能找到目标主机,但是更为详细的选择哪个进程就无能为力了。所以我们需要有端口号。端口号就是主机唯一标识进程的一个16字节整数,拿着IP地址和端口号,我们就能在浩瀚的网络中找到目标主机的目标进程。更为准确的,网络通信本质还是进程间通信,只不过这两个进程可能不在一台主机上。
认识端口号
根据上面介绍,总结端口号的特点:
- 端口号是一个2字节16位的整数
- 端口号用来标识一个进程,告诉操作系统,当前从网卡收到的数据要交给哪一个进程
- IP地址+端口号能在网络世界中标识唯一一个进程
- 同一台主机下,一个端口号只能被一个进程占用
更为具体地:端口号地范围是0-65535,其中
- 0-1023表示的是知名端口号,一般是系统或者是特权进程使用
- 1024-65535:操作系统动态分配的端口号,客户端程序的端口号就是由操作系统从这个范围分配的
端口号和进程ID
我们说到端口号是为了唯一标识一台主机的某个进程,但是为什么不直接使用进程PID呢?进程PID的作用也是标识唯一一个进程呐。原因如下:
- PID标识的是正在运行中的进程,一旦程序退出,这个进程就找不到了
- PID是变化的,可能每次运行程序得到的PID都不一样
- 更深层面上来说,进程ID属于操作系统层面,端口号处于网络层面,如果端口号和进程PID绑定,会让系统进程管理和网络强耦合,实际设计的时候,并没有选择这么做。
理解Socket
综上所述,网络中的两个进程要想相互通信,通信的数据得明确四个属性:源主机的IP+Port,目标主机的IP+Port。我们把IP+Port的组合就称为套接字Socket。
网络字节序
我们知道,数据在内存中的存储方式有大小端之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大小端之分,网络数据流也有大小端之分。如果传输数据双方的主机一个是大端存储,一个是小端存储,假设我们不做任何处理就将数据发送能够给对方,那对方拿到的数据就会出现乱码。为了避免这种情况,我们需要在将数据发送到网络之前将数据转换成网络字节序,具体的:
TCP/IP 协议规定,网络数据流应采用大端字节序,即低地址高字节,所以如果当前发送主机是小端, 就需要先将数据转成大端; 否则就忽略, 直接发送即可。
此外,我们可以在代码中调用相关库函数来做网络字节序和主机字节序的转换:
其中
htonl
函数的作用是将 32 位的长整数从主机字节序转换为网络字节序,例如将 IP 地址转换后准备发送htons
函数的作用是将 16 位的短整数从主机字节序转换为网络字节序,例如将 端口号 地址转换后准备发送ntohl
函数的作用是将 32 位的长整数从网络字节序转换为主机字节序,例如将 接收到的 IP 地址转换后使用ntohs
函数的作用是将 16 位的短整数从网络字节序转换为主机字节序,例如将接收到的端口号转换后使用
注意以上函数区别。
socket编程接口
下面介绍一些常见的socket接口:
C
// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);
// 绑定端口号 (TCP/UDP, 服务器)
int bind(int socket, const struct sockaddr *address,socklen_t address_len);
// 开始监听 socket (TCP, 服务器)
int listen(int socket, int backlog);
// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr* address,socklen_t* address_len);
// 建立连接 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
一般来说,使用socket编程通常需要包含四个头文件
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
创建socket套接字
可以使用socket函数来创建一个套接字
#include <sys/types.h>
#include <sys/socket.h>// 创建一个IPv4的TCP套接字
int socket(int domain, int type, int protocol);
domain
:地址簇,常见的有AF_INET
(IPv4),和AF_INET6
(IPv6)type
:套接字类型,常见的有SOCK_STREAM
(TCP),SOCK_DGRAM
(UDP)protocol
:协议,通常为0(自动选择),也可以指定协议,如IPPROTO_TCP
或IPPROTO_UDP
。- 成功时返回一个套接字描述符,失败时返回-1,并设置error
注意这里的套接字描述符其实就是文件描述符,查看man手册我们可以看到:
也就是说,调用socket这个函数得到一个文件描述符,在操作系统的内核中,它对应于一个数据结构,存储了该套接字的各种状态信息和资源,例如IP地址、端口号、通信协议、缓冲区等。
bind绑定套接字
bind函数将套接字绑定到一个IP地址和端口号。
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd
:套接字描述符addr
:指向ockaddr
结构体的指针,该结构体对象包含了要绑定的地址信息,对于IPv4,使用sockaddr_in
结构体;对于IPv6,使用sockaddr_in6
结构体。addr_len
:addr
指向结构体对象的大小,通常使用sizeof
获取- 成功时返回0,失败时返回-1并设置errno
listen建立监听
listen函数使套接字进入监听状态,准备接受连接请求。
#include <sys/types.h>
#include <sys/socket.h>
int listen(int sockfd, int backlog);
sockfd
:套接字描述符backlog
:挂起连接的最大队列长度,即最多有多少个连接可以等待被接受- 成功时返回0,失败时返回-1并设置errno
accept接受连接
accept函数接受一个连接请求,返回一个新的套接字描述符,用于与客户端通信
#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
sockfd
:监听套接字描述符,即listen获取的套接字描述符addr
指向sockaddr
结构体对象的指针,用于存储客户端地址信息addrlen
:指向addr
指向结构体对象的大小- 成功时返回新的套接字描述符,失败时返回-1并设置errno
connect建立连接
connect函数用于客户端连接到服务器
#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd
:套接字描述符addr
指向sockaddr
结构体对象的指针,用于存储服务器地址信息addrlen
: sockaddr 结构体的大小。- 成功时返回0,失败时返回-1并设置errno
sendto发送数据
sendto
函数是用于在 无连接套接字**(如UDP)上发送数据 的。它允许程序指定目标地址,从而可以在一个套接字上与多个目标进行通信。
#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
sockfd
: 套接字描述符,通过 socket 函数创建buf
: 指向要发送的数据缓冲区len
: 要发送的数据的长度flags
: 发送标志,通常为0dest_add
: 指向sockaddr
结构体的指针,包含目标地址和端口号addrlen
:sockaddr
结构体的大小- 成功时返回发送的字节数,失败时返回-1,并设置 errno 以指示错误
接收数据
recvfrom
函数用于在无连接的套接字(如UDP)上接收数据,它允许程序获取发送数据的源地址。它常用于UDP服务器接收数据包,并且能够知道数据包的来源。
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
sockfd
: 套接字描述符,通过 socket 函数创建。buf
: 指向存储接收数据的缓冲区。len
: 缓冲区的长度,即可以接收的最大字节数。flags
: 接收标志,通常为0。src_addr
: 指向 sockaddr 结构体的指针,用于存储发送方的地址信息。addrlen
: 指向 socklen_t 变量的指针,表示 sockaddr 结构体的大小。调用函数时需要设置为 sockaddr 结构体的大小,函数返回时设置为实际地址的长度。
close关闭套接字
跟关闭文件描述符一样,创建的套接字描述符用完之后也需要手动关闭,同样的使用close函数。
#include<unistd.h>
int close(int fd);
- 成功返回0,失败返回-1
sockaddr结构体
sockaddr 结构体用于存储套接字地址信息。该结构体是网络地址结构体的通用形式。在具体使用时,通常会用到特定协议族的派生结构体,如 sockaddr_in、sockaddr_un。各种网络协议的地址格式并不相同.
- sockaddr:
struct sockaddr {sa_family_t sa_family; // 地址族(Address family)char sa_data[14]; // 套接字地址数据(Socket address data)
};
- sockaddr_in:
struct sockaddr_in {sa_family_t sin_family; // 地址族(AF_INET)in_port_t sin_port; // 端口号(Port number),网络字节序struct in_addr sin_addr; // IPv4地址char sin_zero[8]; // 填充字节,使结构体大小与 `sockaddr` 一致
};
- in_addr:
struct in_addr {uint32_t s_addr; // 32位IPv4地址,网络字节序
};
in_addr 用来表示一个 IPv4 的 IP 地址. 其实就是一个 32 位的整数;
相关文章:
【网络】Socket编程
文章目录 正确理解端口号理解源IP地址和目的IP地址认识端口号端口号和进程ID 理解Socket网络字节序socket编程接口创建socket套接字bind绑定套接字listen建立监听accept接受连接connect建立连接sendto发送数据接收数据close关闭套接字 sockaddr结构体 正确理解端口号 理解源IP…...
【鸿蒙学习笔记】舜和酒店项目开发
这里写目录标题 前期准备1. 环境准备2. 开发工具准备 创建项目1. 使用 deveco-studio 创建 ShunHeHotel 项目2. 把ShunHeHotel 项目使用git进行版本控制3. 提交第1个commit,Alt0 → 输入commit message → 提交4. 查看已经提交的第一个提交5. gitcode 创建同名远程项…...
再进行程序的写时,不要使用eval函数——内建函数eval的坏处!!!!!!!!
一、安全性问题 执行任意代码: eval函数可以执行任意的Python表达式,包括算术运算、逻辑判断、字符串操作等,甚至可以访问当前作用域中的所有变量和函数。这意味着,如果eval处理的字符串来自不可信的源(如用户输入、外…...
Flink HA
目录 Flink HA集群规划 环境变量配置 masters配置 flink-conf.yaml配置 测试 Flink HA集群规划 FLink HA集群规划如下: IP地址主机名称Flink角色ZooKeeper角色192.168.128.111bigdata111masterQuorumPeerMain192.168.128.112bigdata112worker、masterQuorumPee…...
神经网络中如何优化模型和超参数调优(案例为tensor的预测)
总结: 初级:简单修改一下超参数,效果一般般但是够用,有时候甚至直接不够用 中级:optuna得出最好的超参数之后,再多一些epoch让train和testloss整体下降,然后结果就很不错。 高级:…...
使用AJAX发起一个异步请求,从【api_endpoint】获取数据,并在成功时更新页面上的【target_element】
使用AJAX发起一个异步请求,从【api_endpoint】获取数据,并在成功时更新页面上的【target_element】 在Web开发中,使用AJAX(Asynchronous JavaScript and XML,异步JavaScript和XML)可以实现在不刷新整个页面…...
【AI绘画教程】Stable Diffusion 1.5 vs 2
在本文中,我们将总结稳定扩散 1 与稳定扩散 2 辩论中的所有要点。我们将在第一部分中查看这些差异存在的实际原因,但如果您想直接了解实际差异,您可以跳下否定提示部分。让我们开始吧! Stable Diffusion 2.1 发布与1.5相比&#x…...
纯前端小游戏,4096小游戏,有音效,Html5,可学习使用
// 游戏开始运行create: function(){this.fieldArray [];this.fieldGroup this.add.group();this.score 0;//4096 增加得分this.bestScore localStorage.getItem(gameOptions.localStorageName) null ? 0 : localStorage.getItem(gameOptions.localStorageName);for(var …...
ROS、pix4、gazebo、qgc仿真ubuntu20.04
一、ubuntu、ros安装教程比较多,此文章不做详细讲解。该文章基于ubuntu20.04系统。 pix4参考地址:https://docs.px4.io/main/zh/index.html 二、安装pix4 1. git clone https://github.com/PX4/PX4-Autopilot.git --recursive 2. bash ./PX4-Autopilot…...
qt 国际化语言,英文和中文切换
1、把需要翻译转换的内用用tr()包含,比如: label->setText("hello word"); 2、在 .pro 文件中添加 TRANSLATIONS lang_en.ts \ lang_zn.ts 3、利用lupdate 工具提取…...
机器学习入门【经典的CIFAR10分类】
模型 神经网络采用下图 我使用之后发现迭代多了之后一直最高是正确率65%左右,然后我自己添加了一些Relu激活函数和正则化,现在正确率可以有80%左右。 模型代码 import torch from torch import nnclass YmModel(nn.Module):def __init__(self):super(…...
01 安装
安装和卸载中,用户全部切换为root,一旦安装,普通用户也能使用 初期不进行用户管理,全部用root进行,使用mysql语句 1. 卸载内置环境 检查是否有mariadb存在,存在走a部分卸载 ps axj | grep mysql ps ajx |…...
AI 模型本地推理 - YYPOLOE - Python - Windows - GPU - 吸烟检测(目标检测)- 有配套资源直接上手实现
Python 运行 - GPU 推理 - windows 环境准备python 代码 环境准备 FastDeploy预编译库下载 conda config --add channels conda-forge && conda install cudatoolkit11.2 cudnn8.2 pip install fastdeploy_gpu_python-0.0.0-cp38-cp38-win_amd64.whlpython 代码 impo…...
全国媒体邀约,主流媒体到场出席采访报道
传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 全国媒体邀约,确保主流媒体到场出席采访报道,可以带来一系列的好处,这些好处不仅能够增强活动的可见度,还能对品牌或组织的长期形象产生积…...
计算机视觉8 图像增广
图像增广(image augmentation)是通过对训练图像进行一系列随机改变,从而产生相似但又不同的训练样本的技术。 图像增广有以下两个主要作用: 扩大训练数据集的规模;随机改变训练样本可以降低模型对某些属性的依赖&#…...
Transformer中的自注意力是怎么实现的?
在Transformer模型中,自注意力(Self-Attention)是核心组件,用于捕捉输入序列中不同位置之间的关系。自注意力机制通过计算每个标记与其他所有标记之间的注意力权重,然后根据这些权重对输入序列进行加权求和,…...
LabVIEW鼠标悬停在波形图上的曲线来自动显示相应点的坐标
步骤 创建事件结构: 打开LabVIEW,创建一个新的VI。 在前面板上添加一个Waveform Graph控件。 在后面板上添加一个While Loop和一个事件结构(Event Structure)。 配置事件结构,选择Waveform Graph作为事件源…...
操作系统发展简史(Unix/Linux 篇 + DOS/Windows 篇)+ Mac 与 Microsoft 之风云争霸
操作系统发展简史(Unix/Linux 篇) 说到操作系统,大家都不会陌生。我们天天都在接触操作系统 —— 用台式机或笔记本电脑,使用的是 windows 和 macOS 系统;用手机、平板电脑,则是 android(安卓&…...
钡铼分布式 IO 系统 OPC UA边缘计算耦合器BL205
深圳钡铼技术推出的BL205耦合器支持OPC UA Server功能,以服务器形式对外提供数据。符合IEC 62541工业自动化统一架构通讯标准,数据可以选择加密(X.509证书)、身份验证方式传送。 安全策略支持basic128rsa15、basic256、basic256s…...
实现了一个心理测试的小程序,微信小程序学习使用问题总结
1. 如何在跳转页面中传递参数 ,在 onLoad 方法中通过 options 接收 2. radio 如何获取选中的值? bindchange 方法 参数e, e.detail.value 。 如果想要获取其他属性,使用data-xx 指定,然后 e.target.dataset.xx 获取。 3. 不刷…...
vue是如何进行监听数据变化的?vue2和vue3分别是什么?vue3为什么要更换?
Vue如何进行监听数据变化的? Vue.js 通过其响应式系统来监听数据变化。这个系统允许你声明式地将数据和 DOM 绑定,一旦数据发生变化,相关的 DOM 将自动更新。Vue 使用以下机制来实现数据的监听和响应: 响应式数据:在 …...
数据结构day3
一、思维导图 二、 #include "seqlist.h"#include<myhead.h> int main(int argc, const char *argv[]) {//创建一个顺序表SeqListPtr L list_create();if(NULL L){return -1;}//调用添加函数list_add(L,123);list_add(L,435);list_add(L,856);list_add(L,65…...
免费的数字孪生平台助力产业创新,让新质生产力概念有据可依
关于新质生产力的概念,在如今传统企业现代化发展中被反复提及。 那到底什么是新质生产力?它与哪些行业存在联系,我们又该使用什么工具来加快新质生产力的发展呢?今天我将介绍一款为发展新质生产力而量身定做的数字孪生工具。 新…...
mtsys2 编译 qemu 记录
参考链接 下载 MSYS2 MSYS2 MSYS2 换源 进入目录\msys64\etc\pacman.d, 在文件mirrorlist.msys的前面插入 Server http://mirrors.ustc.edu.cn/msys2/msys/$arch在文件mirrorlist.mingw32的前面插入 Server http://mirrors.ustc.edu.cn/msys2/mingw/i686在…...
【Python数据分析】数据分析三剑客:NumPy、SciPy、Matplotlib中常用操作汇总
文章目录 NumPy常见操作汇总SciPy常见操作汇总Matplotlib常见操作汇总官方文档链接NumPy常见操作汇总 在Python的NumPy库中,有许多常用的知识点,这里列出了一些核心功能和常见操作: 类别函数或特性描述基础操作np.array创建数组np.shape获取数组形状np.dtype查看数组数据类…...
STM32智能家居电力管理系统教程
目录 引言环境准备智能家居电力管理系统基础代码实现:实现智能家居电力管理系统 4.1 数据采集模块 4.2 数据处理与控制模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景:电力管理与优化问题解决方案与优化收尾与总结 1. 引言 智能家居电…...
C# 邮件发送
创建邮件类 // 有static时候 类名,方法名// MyEmail.方法名/// <summary>/// 给目标发送邮箱/// </summary>/// <param name"maiTo"></param>/// <param name"title"></param>/// <param name"con…...
Kotlin 协程简化回调
suspend 和 suspendCoroutine 实现 suspendCoroutine函数必须在协程作用域或挂起函数中才能调用,它接收一个Lambda表达式参数,主要作用是将当前协程立即挂起,然后在一个普通的线程中执行Lambda表达式中的代码。Lambda表达式的参数列表上会传…...
帝王蝶算法(EBOA)及Python和MATLAB实现
帝王蝶算法(Emperor Butterfly Optimization Algorithm,简称EBOA)是一种启发式优化算法,灵感来源于蝴蝶群体中的帝王蝶(Emperor Butterfly)。该算法模拟了帝王蝶群体中帝王蝶和其他蝴蝶之间的交互行为&…...
【学术会议征稿】第六届信息与计算机前沿技术国际学术会议(ICFTIC 2024)
第六届信息与计算机前沿技术国际学术会议(ICFTIC 2024) 2024 6th International Conference on Frontier Technologies of Information and Computer 第六届信息与计算机前沿技术国际学术会议(ICFTIC 2024)将在中国青岛举行,会期是2024年11月8-10日,为…...
大连网页模板建站/百度扫一扫
sql小计汇总 rollup用法实例分析更新时间:2009年06月26日 17:47:28 作者:rollup在oracle ,sql-server里面都有有。这里介绍sql server2005里面的一个使用实例:CREATE TABLE tb(province nvarchar(10),city nvarchar(10),score int)INSERT t…...
免费空间做网站/免费python在线网站
本文适用于将MyEclipse上的项目projectA检出后重命名为projectB的情况,如果只是检出projectA到Eclipse,也可以部分参考 1、从svn上检出Myeclipse项目到Eclipse 检出后,首先断开svn连接。 2、更改项目名称 从svn检出的项目projectA,…...
无锡专业做网站/今天的新闻内容
题目描述编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉…...
林州网站建设服务/百度服务中心
2019独角兽企业重金招聘Python工程师标准>>> dSploitzANTI渗透教程之HTTP服务重定向地址 HTTP服务 HTTP服务主要用于重定向地址的。当用户创建一个钓鱼网站时,可以通过使用HTTP服务指定,并通过实施中间人攻击,使客户端访问该钓鱼网…...
做门面商铺比较好的网站/百度统计官网
最近项目中通过Kubernetes部署Prometheus完成可视化大屏数据采集,特此记录便于日后查阅。 一、Prometheus部署 1、deploy.yaml apiVersion: apps/v1 kind: Deployment metadata:labels:name: prometheus-deploymentname: prometheusnamespace: monitoring spec:re…...
高端网站设计收费/谷歌优化师
数字化时代客户体验管理与卓越厅堂服务课程背景: 数字化浪潮下,很多网点存在以下问题:不清楚如何提升网点数字化客户体验?不清楚网点数字化客户体验应用案例?不积善成德如何打造网点卓越厅堂服务? 课…...