网络编程套接字 | 预备知识

news2024/11/25 12:43:37

在之后的文章中我们将来讲解网络编程中的相关知识点,再本文中我们首先来讲解一下网络编程中的预备知识:

预备知识

源IP地址和目的IP地址

在IP数据包中有两个IP地址分别是源IP地址和目的IP地址,此时这里就会出现一个问题就是:如果我们光有IP地址,是无法完成通信的。有了IP地址只能够将消息发送到对方的机器上,但是还徐亚欧有一个其他的标识位来进行区分,这个数据需要发送给哪一个程序进行解析。

端口号

端口号是(port)是传输层协议的内容

  • 端口号是一个2字节16位的整数;
  • 端口号用来标识一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理;
  • IP地址 + 端口号能够标识网络上的某一台主机的某一个进程;
  • 一个端口号只能被一个进程占用。
    需要注意的是:一个进程可以绑定多个端口号,但是一个端口号不能被多个进程绑定

理解端口号和进程ID

之前我们在学习系统编程的时候,学习过在Linux中pid可以表示一个进程;此处在网络编程中端口号也表示唯一的一个进程,那么这两者有什么关系?对于此处的理解在我看来就是:我们使用的操作系统有很多,那么就意味着每一个操作系统都有着自己的进程ID的处理方式,但是网络在目前只有一个,所有的操作系统都需要接入这个网络,有了端口号就可以让网络在各个操作系统上都可以正常的运行,不用让网络来对操作系统进行适配,同时可以让网络与操作系统进行解耦。

认识TCP协议和UDP协议

在此处我们简单直观的了解一下TCP协议和UDP协议,后面我们再对其进行详细的学习。

TCP协议

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

UDP协议

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

网络字节序

在之前学习C语言的时候,我们遇到过一个问题就是:计算机内存中的多字节序对于内存地址有大段和小段之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大段小段之分。对于网络数据流来说同样有着大段小段之分。

  • 发送主机通常将发送缓冲区的数据按照内存地址从低到高的顺序发出
  • 接受主机把网络上接收到的字节依次保存在接受缓冲区中,也是按照内存地址从低到高的顺序保存
  • 因此网络数据流的地址应该这样规定:先发出的数据是低地址,后发出的数据是高地址
  • TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节
  • 不管这台主机是大端机还是小端机,都会按照这个TCP/IP规定的网络字节序来发送/接收数据;如果当前发送主机是小端,就需要将数据转成大端;否则就忽略,直接发送即可。
    例子:将0x1234abcd写入到以0x0000开始的内存中,则结果为:
big-endianlittle-endian
0x00000x120xcd
0x00010x340xab
0x00020xab0x34
0x00030xcd0x12
为了使网络程序具有可移植性,使同样的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为短整数
// htonl 表示将32位的长整数从主机字节序转换成网络字节序,例如将IP地址转化后准备发送
// 如果主机是小段字节序,这些函数将参数做相应的大小端转换然后返回
// 如果主机是大段字节序,这些函数将不做转换,将参数原封不动的返回

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

在上述的API中我们都可以看到一个类型 – struct sockaddr结构
socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、 IPv6。然而, 各种网络协议的地址格式并不相同。
struct sockaddr和struct sockaddr_in这两个结构体用来处理网络通信的地址。

  • 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结构体指针做为参数;
    在这里插入图片描述

sockaddr结构

/* Structure describing a generic socket address.  */
struct sockaddr
  {
    __SOCKADDR_COMMON (sa_);	/* Common data: address family and length.  */
    char sa_data[14];		/* Address data.  */
  };

虽然socket api的接口是sockaddr,但是我们真正在基于IPv4编程时,使用的结构是sockaddr_in,这个结构体中主要有三部分信息:地址类型,端口号,IP地址

sockaddr_in

/* Structure describing an Internet socket address.  */
struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;			/* Port number.  */
    struct in_addr sin_addr;		/* Internet address.  */

    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr) -
			   __SOCKADDR_COMMON_SIZE -
			   sizeof (in_port_t) -
			   sizeof (struct in_addr)];
  };
// ----------------------------------------------------------------- 
// __SOCKADDR_COMMON (sin_);的定义如下:
/* 
#define	__SOCKADDR_COMMON(sa_prefix) \
  sa_family_t sa_prefix##family
  
sa_prefix##family 是一个预处理宏中的宏替换语法。它的作用是将两个标识符合并成一个单词,并用于创建结构体的字段名。在这个语法中:
sa_prefix 是一个标识符(通常是一个结构体字段的前缀),它是宏的一个参数。
## 是预处理器中的连接运算符,用于将两个标识符连接在一起,形成一个新的标识符。
family 是另一个标识符(通常是表示套接字地址族的字段名称),它在这里与 sa_prefix 合并。

// Type to represent a port.
typedef uint16_t in_port_t;

// Internet address.
typedef uint32_t in_addr_t;
struct in_addr
  {
    in_addr_t s_addr;
  };
*/

后面的文章中我们将开始使用UDP协议、TCP协议等来进行代码的编写。

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

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

相关文章

Spring MVC 之MVC 体系结构、什么是SpringMVC

Spring MVC简介 MVC 体系结构三层架构MVC设计模式 Spring MVC 是什么&#xff1f;扩展知识Spring模块Data Access/Integration&#xff08;数据访问/集成&#xff09;Web&#xff08;网络层&#xff09;AOP&#xff08;面向切面&#xff09;Messaging&#xff08;消息传送&…

Invalid bound statement (not found): com.test.mapper.ItemsMapper.selectItems

分析原因 如下图&#xff0c;因为idea默认只会扫描resources目录下xml的文件&#xff0c;所有java目录下ItemsMapper.xml没有被扫描到&#xff0c;导致Invalid bound statement (not found): com.test.mapper.ItemsMapper.selectItems 解决办法 在pom文件中&#xff0c;增加…

【LeetCode-中等题】47. 全排列 II

文章目录 题目方法一&#xff1a;递归回溯去重 题目 相比较46题&#xff1a;不需要去重&#xff1a;【LeetCode-中等题】46. 全排列 需要做出的改变就是&#xff1a; 首先需要对待全排列的数组进行排序&#xff08;为去重操作做准备&#xff09; Arrays.sort(nums);//对数组…

Nacos Java SDK

概述部分 Maven 坐标 <dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId><version>${version}</version> </dependency>注意&#xff1a;由于Nacos Java SDK在2.0版本后引入了gRPC&am…

直播邀约|8个数字了解2023腾讯全球数字生态大会

2023腾讯数字生态大会&#xff0c;一起来看看吧~

NoSQL之Redis配置与优化(一)

关系数据库与非关系型数据库 &#xff1a; ●关系型数据库&#xff1a; 关系型数据库是一个结构化的数据库&#xff0c;创建在关系模型&#xff08;二维表格模型&#xff09;基础上&#xff0c;一般面向于记录。 SQL 语句&#xff08;标准数据查询语言&#xff09;就是一种基于…

软件工程:万字长文,说透常见的5种部署策略(文末有总结)

在软件工程中&#xff0c;最终的价值交付&#xff0c;都是要通过软件的部署上线来完成的。 那如何将新的或改进的软件功能交付给用户&#xff0c;同时还要确保高质量、稳定性和用户体验&#xff0c;选择适当的部署策略变得至关重要。 复杂软件工程中&#xff0c;新功能的部署…

GC Root

开章&#xff0c;不知道有没有小伙伴跟我一样&#xff0c;在快要毕业或者换工作的时候疯狂刷八股文&#xff0c;这样做有什么坏处呢 好多面试题自己都是靠死记硬背&#xff0c;这也是我们过后压根记不着这些内容的原因&#xff1b;每次面试问题需要自己反复去刷&#xff0c;甚…

C++初阶:C++入门

目录 一.iostream文件 二.命名空间 2.1.命名空间的定义 2.2.命名空间的使用 三.C的输入输出 四.缺省参数 4.1.缺省参数概念 4.2.缺省参数分类 4.3.缺省参数注意事项 4.4.缺省参数用途 五.函数重载 5.1.重载函数概念 5.2.C支持函数重载的原理--名字修饰(name Mangl…

富士康曲线救国,iPhone 15 Pro订单较上代有减少,iPhone 15增加

据外媒报道&#xff0c;苹果将于9月13日凌晨举行的秋季新品发布会上推出iPhone 15系列智能手机。然而&#xff0c;令人惊讶的是&#xff0c;这款备受期待的手机在8月份就已开始批量生产&#xff0c;以确保上市初期供应充足。 随着iPhone 15系列发布时间的临近&#xff0c;越来越…

Cisco 5580 ASA service 如何Console?

一、Cisco ASA 5580 需要一个9针转Rj45到头子 如图&#xff1a; 二、插在设备的这个接口上 就可以了

RabbitMQ从入门到精通之安装、通讯方式详解

文章目录 RabbitMQ一、RabbitMQ介绍1.1 现存问题 一、RabbitMQ介绍二、RabbitMQ安装三、RabbitMQ架构四、RabbitMQ通信方式4.1 RabbitMQ提供的通讯方式4.2 Helloworld 方式4.2Work queues4.3 Publish/Subscribe4.4 Routing4.5 Topics4.6 RPC (了解) 五、Springboot 操作RabbitM…

《C和指针》读书笔记(第十三章 高级指针话题)

目录 0 简介1 进一步探讨指向指针的指针2 高级声明3 函数指针3.1 回调函数3.2 转移表 4 命令行参数4.1 传递命令行参数4.2 处理命令行参数 5 字符串常量6 总结 0 简介 众所周知&#xff0c;指针是C语言的灵魂&#xff0c;所以本书&#xff08;《C和指针》&#xff09;才会将较…

为安全带来光明:光耦继电器的 10 种救生应用

在安全性和可靠性至关重要的世界中&#xff0c;光耦继电器已成为推动各行业进步的关键技术。这些卓越的设备经常在主流新闻中被忽视&#xff0c;但它们一直在默默地为保障生命和提高整体运营效率的关键系统提供动力。今天&#xff0c;我们重点介绍光耦继电器的十种救生应用&…

设计模式-01简单工厂模式详解 详细代码对比

目录 ChatGpt问答原生代码简单工厂模式代码 简单工厂模式&#xff08;Simple Factory Pattern&#xff09;新增boat 对比两种方法原生代码为什么使用强制转换&#xff1f;简单工厂模式 简单工厂方法总结与原生代码的区别&#xff1a;优点:缺点&#xff1a; 参考 本文将介绍什么…

golang指针的学习笔记

package main // 声音文件所在的包&#xff0c;每个go文件必须有归属的包 import ("fmt" )// 引入程序中需要用的包&#xff0c;为了使用包下的函数&#xff0c;比如&#xff1a;Printin// 字符类型使用 func main(){ // 基本数据类型&#xff0c;变量存的就是值&am…

做tiktok怎么运营?

一、揭开tiktok的神秘面纱 说到tiktok&#xff0c;你可能想到的是那些精彩的短视频&#xff0c;以及那些在几秒钟内就能吸引无数粉丝的创作者。然而&#xff0c;tiktok的魅力远不止于此。这个全球最受欢迎的短视频社交平台&#xff0c;正以惊人的速度改变着社交媒体的面貌。 二…

【IR】Vision-Language Tracking

调研&#xff1a;视觉-语言跟踪 0x01 Transformer vision-language tracking via proxy token guided cross-modal fusion, PRL2023AbstractIntroductionContribution效果Conclusion 0x02 Divert More Attention to Vision-Language Object Tracking, NeurIPS2022AbstractIntro…

起飞!Python 3.11的10个高效新特性

性能有巨大的提升是Python 3.11的一个重要的改进&#xff0c;除此以外Python 3.11还有增加了许多新的特性。在本文中我们将介绍Python 3.11新特性&#xff0c;通过代码示例演示这些技巧如何提高生产力并优化代码。 1、模式匹配 Python 3.11引入了模式匹配&#xff0c;可以简化…

OpenAI 函数调用教程

推荐&#xff1a;使用 NSDT场景编辑器 快速搭建3D应用场景 什么是OpenAI函数调用&#xff1f; OpenAI API 非常擅长以系统的方式生成响应。只需几行代码即可管理提示、优化模型输出以及执行、生成和语言应用程序。 即使有这么多好东西&#xff0c;OpenAI API对开发人员和工程…