Liinux——(网络)socket编程

预备知识

源IP地址和目的IP地址

  • 在IP数据包头部中, 有两个IP地址, 分别叫做源IP地址, 和目的IP地址

认识端口号

  • 端口号(port)是传输层协议的内容.
  • 端口号是一个2字节16位的整数;
  • 端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪个进程来处理;
  • IP地址 + 端口号能够标识网络上的某一台主机的某一个进程;
  • 一个端口号只能被一个进程占用

传输层协议(TCP和UDP)的数据段中有两个端口号, 分别叫做源端口号和目的端口号. 就是在描述 "数据是谁发的, 要发给谁

简单认识TCP协议

  • 传输层协议
  • 有连接
  • 可靠传输
  • 面向字节流

简单认识UDP协议

  • 传输层协议
  • 无连接
  • 不可靠传输
  • 面向数据报

网络字节序

我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分, 网络数据流同样有大端小端之分. 那么如何定义网络数据流的地址呢?

补充
计算机在存储数据时是有大小端的概念的:
大端模式: 数据的高字节内容保存在内存的低地址处,数据的低字节内容保存在内存的高地址处。
小端模式: 数据的高字节内容保存在内存的高地址处,数据的低字节内容保存在内存的低地址处。
在这里插入图片描述

  • 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;
  • 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;
  • 因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址.
  • TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节.
  • 不管这台主机是大端机还是小端机, 都会按照这个TCP/IP规定的网络字节序来发送/接收数据;
  • 如果当前发送主机是小端, 就需要先将数据转成大端; 否则就忽略, 直接发送即可;

网络字节序与主机字节序之间的转换
为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。

#include <arpa/inet.h>uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
  • 这些函数名很好记,h表示host,n表示network,l表示32位长整数,s表示16位短整数。ntoh表示网络转主机,hton表示主机转网络
  • 例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
  • 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回;
  • 如果主机是大端字节序,这些 函数不做转换,将参数原封不动地返回。

socket编程接口

socket常见API

创建 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);

在上面的的这些接口中可以发现,这里面有一个结构体指针sockaddr* ,那么这个sockaddr结构体到底是什么呢?

sockaddr结构

socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,以及后面要讲的UNIX DomainSocket. 然而, 各种网络协议的地址格式并不相同

在这里插入图片描述
这些结构体中 struct sockadd_in 表示基于网络 进行网络通信的套接字;
struct sockaddr_un叫做域间套接字,用来两个进程之间进行本地通信的这个是取代system V本地之间进行通信的解决方案

  • IPv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位地址类型, 16
    位端口号和32位IP地址.
  • IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET6. 这样,只要取得某种sockaddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容.
  • *socket API可以都用struct sockaddr 类型表示, 在使用的时候需要强制转化成sockaddr_in; 这样的好处是程序的通用性, 可以接收IPv4, IPv6, 以及UNIX Domain Socket各种类型的sockaddr结构体指针做为
    参数

U简单的UDP网络程序

udp_client.cc

#include "udp_client.hpp"int main()
{std::cout << "hello client" << std::endl;return 0;
}

udp_server.cc

#include "udp_server.hpp"
#include <memory>using namespace ns_server;
using namespace std;int main()
{unique_ptr<UdpServer> usvr(new UdpServer("1.1.1.1", 8082));usvr->InitServer(); //服务器的初始化usvr->Start();return 0;
}

udp_client.hpp

#pragma once#include <iostream>

udp_server.hpp

#pragma once#include <iostream>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>namespace ns_server
{enum{SOCKET_ERR=1,BIND_ERR};const static uint16_t default_port = 8080;class UdpServer{public:UdpServer(std::string ip, uint16_t port = default_port): ip_(ip), port_(port){std::cout << "server addr: " << ip << " : " << port_ << std::endl;}void InitServer(){// 1. 创建socket接口,打开网络文件sock_ = socket(AF_INET, SOCK_DGRAM, 0);if(sock_ < 0){std::cerr << "create socket error: " << strerror(errno) << std::endl;exit(SOCKET_ERR);}std::cout << "create socket success: " << sock_ << std::endl; //3// 2. 给服务器指明IP地址(??)和Portstruct sockaddr_in local;  // 这个 local 在哪里定义呢?用户空间的特定函数的栈帧上,不在内核中!bzero(&local, sizeof(local));local.sin_family = AF_INET; //PF_INETlocal.sin_port = htons(port_);// inet_addr: 1,2// 1. 字符串风格的IP地址,转换成为4字节int, "1.1.1.1" -> uint32_t -> 能不能强制类型转换呢?不能,这里要转化// 2. 需要将主机序列转化成为网络序列local.sin_addr.s_addr = inet_addr(ip_.c_str());if(bind(sock_, (struct sockaddr*)&local, sizeof(local)) < 0){std::cerr << "bind socket error: " << strerror(errno) << std::endl;exit(BIND_ERR);}std::cout << "bind socket success: " << sock_ << std::endl; //3}void Start(){}~UdpServer() {}private:int sock_;uint16_t port_;std::string ip_; // 后面要专门研究一下,后面要去掉这个ip};
} // end NS_SERVER

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/727961.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tomcat搭建个人博客 实现动静分离

jar包相关 .war&#xff1a;WebApp打包,类zip格式文件,通常包括一个应用的所有资源,比如jsp,html,配置文件等 .jar&#xff1a;EJB类文件的打包压缩类zip格式文件&#xff0c;,包括很多的class文件, 网景公司发明 .rar&#xff1a;资源适配器类打包文件&#xff0c;目前已不常…

[数据结构]OJ用队列实现栈

225. 用队列实现栈 - 力扣&#xff08;LeetCode&#xff09; 官方题解&#xff1a;https://leetcode.cn/problems/implement-stack-using-queues/solutions/432204/yong-dui-lie-shi-xian-zhan-by-leetcode-solution/ 首先我们要知道 栈是一种后进先出的数据结构&#xff0c…

python环境搭建(Python 3.11.8)

文章目录 1 安装Python2 使用虚拟环境3 Python程序打包为二进制 1 安装Python 按照linux安装python3文档安装python3&#xff0c;只是在编译python3时添加一个选项&#xff1a;--enable-shared&#xff0c;该选项是为了后续可以将程序打包为二进制&#xff0c;如果不需要该功能…

C++后端技术:编译 静态链接和动态连接

静态连接 在编译时间完成&#xff0c;所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件&#xff0c;通常为“libxxx.a”的形式 粉丝福利&#xff0c; 免费领取C/C 开发学习资料包、技术视频/项目代码&#xff0c;1000道大厂面试题&#xff0c;内容包括&#xff08…

艺术与科技的结合,AI绘画图生图怎么样?

AI绘画图生图是指通过人工智能技术生成的具有艺术价值的图像。它可以根据用户提供的参考图像或描述&#xff0c;自动生成具有艺术风格的新图像。这些图像可以是风景、人物、抽象画等各种形式。那么ai绘画图生图到底怎么样&#xff1f; AI绘画图生图的优点在于它可以快速、高效地…

基于springboot+vue的高校教师电子名片系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Jenkins Error 403 No valid crumb was included in the request

WARNING hudson.security.csrf.CrumbFilter#doFilter: No valid crumb was included in request for /pluginManager/installPlugins by admin. Returning 403. 找到Jenkins安装目录&#xff0c;我的是centos yum方式安装的&#xff0c;在 /var/lib/jenkins 修改该目录下的co…

ANTLR4规则解析生成器(三):遍历语法分析树

文章目录 1 词法分析2 语法分析3 遍历语法分析树3.1 Listener3.2 Visitor 4 总结 1 词法分析 词法分析就是对给定的字符串进行分割&#xff0c;提取出其中的单词。 在antlr4中&#xff0c;词法规则的名称的首字母需要大写&#xff0c;右侧必须是终结符&#xff0c;通常将词法…

力扣经典题目解析--反转链表

原题地址: . - 力扣&#xff08;LeetCode&#xff09; 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 题目解析 链表&#xff08;Linked List&…

仓储管理系统(WMS) 的研发历程-PRD撰写

题外话&#xff1a;PRD的展现形式有多种&#xff0c;有的人喜欢在axure上直接做产品描述&#xff0c;觉得word较为过时&#xff0c;有的人认为axure不专业&#xff0c;任何展现形式都无可厚非&#xff0c;重要的达到PRD的目的&#xff0c;PRD的目标是让团队知道需求实现细节&am…

启动Docker镜像时候,ENTRYPOINT 和CMD这两者指令的写法有什么不同和区别?

ENTRYPOINT和CMD在Dockerfile中都用于指定容器启动时执行的命令&#xff0c;但它们之间存在一些关键的区别和不同的用途&#xff1a; 1. 基本用途和行为差异 ENTRYPOINT 定义了容器启动时执行的基础命令&#xff0c;使得容器像一个可执行程序。ENTRYPOINT让你能够指定容器启动…

抖店类目报白什么意思?什么类目需要报白?这次给你讲明白!

我是电商珠珠 不少新手在选择类目的时候&#xff0c;有些类目却无法选择&#xff0c;系统显示需要报白才可以。那什么是报白&#xff1f;怎么报白&#xff1f;今天我就一次性给你们讲清楚。 抖店类目报白什么意思&#xff1f; 根据官方的说法&#xff0c;报白就是针对一些比…

经验分享:水牛社怎么做?

本人也就是通过他慢慢学习成长起来的。还是一个网友推荐的&#xff0c;现在他对我来说算是大佬了&#xff0c;已经单飞了&#xff0c;好久都没有联系了&#xff0c;呵呵&#xff0c;真是人往高处走&#xff0c;水往低处流啊。 做网赚会经常和一些网络小白聊天&#xff0c;聊着…

回调函数、回调地狱、解放方法Promise的用法

回调函数 回调函数的定义非常简单&#xff1a;一个函数被当做一个实参传入到另一个函数(外部函数)&#xff0c;并且这个函数在外部函数内被调用&#xff0c;用来完成某些任务的函数。就称为回调函数回调函数的两种写法(实现效果相同)&#xff1a; const text () > {docum…

使用Ora2Pg迁移oracle数据到openGauss

下载说明&#xff1a; Perl DBD&#xff1a; http://search.CPAN.org #只需在搜索输入框中输入模块的全名&#xff08;例如&#xff1a;DBD::Oracle、DBD::Pg&#xff09; Ora2Pg&#xff1a;https://ora2pg.darold.net/start.html在Windows下&#xff0c;应该安装Strawbe…

Java中可以实现的定时任务策略

Java中可以实现的定时任务策略 文章目录 Java中可以实现的定时任务策略自定义独立线程JDK提供的调度线程池-**ScheduledExecutorService**内核是Spring的Task执行调度quartz调度 #mermaid-svg-mQ9rPqk0Ds3ULnvD {font-family:"trebuchet ms",verdana,arial,sans-seri…

个人项目介绍4:三维园区篇

个人项目介绍: 地图铁路线路篇 地球卫星篇 火车站篇 三维园区篇 项目需求&#xff1a; 1.按比例全景显示三维园区 2.精确显示园区内设备设施 3.实时显示设备报警信息 4.显示园区内摄像监控设备&#xff0c;并可点击显示监控视频流 5.显示园区内的重大危险源和风险分布 …

ASPICE SYS3架构设计文档编写规范

一、文档目的与范围 本规范旨在指导新能源汽车电池管理系统(BMS)的开发团队按照ASPICE (Automotive SPICE) 的SYS3级别要求来编写详细的系统架构设计文档。文档应涵盖从概念设计到具体实现的所有关键系统架构决策和设计细节,确保系统的可追溯性、完整性及一致性。 二、文…

PCL 路面点云标线提取(C++详细过程版)

目录 一、算法原理二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 算法来自本人自创。实现效果如下图所示,具体实现原理看代码即可。 二、代码实现 #include

bean的管理方式

默认情况下&#xff0c;spring项目启动时&#xff0c;会把bean对象全部创建好放到ioc容器 主动获取bean对象&#xff1a;getBean里面传入bean的名称或bean的类型 注意如果没有主动设置bean的名称&#xff0c;则默认名称是对应类名的首字母小写 在ioc容器中&#xff0c;bean对…