网络编程套接字(1)

文章目录

  • 网络编程套接字(1)
    • 1. 预备知识
      • 1.1 源IP与目的IP
      • 1.2 认识端口号
      • 1.3 理解 "端口号" 和 "进程ID"
      • 1.4 源端口号和目的端口号
      • 1.5 认识TCP协议和UDP协议
        • (1) TCP
        • (2) UDP
      • 1.6 网络字节序
    • 2. socket编程接口
      • 2.1 socket 常见API
      • 2.2 sockaddr结构

网络编程套接字(1)

1. 预备知识

1.1 源IP与目的IP

  • 在IP数据包头部中, 有两个IP地址, 分别叫做源IP地址, 和目的IP地址。
  • 源IP地址:发送主机的IP地址
  • 目的IP地址:接收主机的IP地址

1.2 认识端口号

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

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

1.3 理解 “端口号” 和 “进程ID”

  • A主机把数据发送给B主机是目的吗?
    不是的,这只是一种手段,我们其实是要把A主机上的数据交给B主机上的某种服务。(本质是某种客户端和某种服务器)

  • 我们平时想看抖音短视频必须打开抖音APP,打开抖音APP就是启动抖音的客户端,本质是一个进程;同时我们能在任意时间刷短视频,是因为抖音的服务器在 7*24小时内以进程的方式在运行;所以我们所有的请求动作不是由主机A发起的,而是由主机A上的客户端进程发起的,后与主机B上的服务器进程进行通信。

  • 网络通信本质其实是进程间通信

在这里插入图片描述

  • 通信的两个阶段:

    • 先将数据通过OS,将数据发送到目标主机(手段)

      • TCP/IP协议完成。IP可以标识互联网上唯一的一台主机
    • 再在本机收到的数据,推送给自己上层的指定进程

      • 端口号可以标识对应主机内,唯一的一个进程
  • IP地址 + 端口号 = 互联网中唯一的一个进程 (目前)

[源IP,源端口号;目的IP,目的端口] 可以标识互联网中唯二的两个进程,我们把这种通信方式叫做: socket通信

网络通信的本质:是通过IP地址 + 端口号构建进程的唯一性,来进行基于网络的进程间通信IP

问题:

  • 端口号,为什么不用进程PID来标识进程的唯一性?

    • 不是所有进程都要进行网络通信,只有部分进程进行网络通信,用PID很难区分两者(不进行网络通信和进行网络通信)
    • 网络功能设计上要使用PID字段,PID是OS层面进程管理的概念,这么做意味着网络模块要增加进程管理的部分,增加了进程管理和网络管理的耦合度
  • 一个端口号只能被一个进程绑定,一个进程可以关联多个端口号

理解: 在OS层面上可以维护一张哈希表,进程在绑定port时就是把PID填入哈希表中,哈希表中下标唯一,一个PID可以对应很多下标;所以在数据报到来时,OS可以根据报文的目的端口号查哈希表找到对应进程,未来把数据交给进程

在这里插入图片描述

1.4 源端口号和目的端口号

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

1.5 认识TCP协议和UDP协议

(1) TCP

此处我们先对TCP(Transmission Control Protocol 传输控制协议)有一个直观的认识; 后面我们再详细讨论TCP的一些细节问题。

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

(2) UDP

此处我们也是对UDP(User Datagram Protocol 用户数据报协议)有一个直观的认识; 后面再详细讨论。

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

1.6 网络字节序

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

  • 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;
  • 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;
  • 因此,网络数据流的地址应这样规定: 先发出的数据是低地址,后发出的数据是高地址
  • 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位短整数。
  • 例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
  • 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回;
  • 如果主机是大端字节序,这些 函数不做转换,将参数原封不动地返回。

2. socket编程接口

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

说明: 参数在使用时在详细解释

2.2 sockaddr结构

上面是一套网络通信的接口,sockaddr是这些接口中最重要的参数

  • sockaddr_in:是用于网络通信的套接字,

  • sockaddr_un:是用于域间通信(本地通信)的套接字,用来取代system V原始通信的方案

  • sockaddr:是一套通用的接口,既可以本地通信又可以网络通信

但是我们在使用函数的时候,传的参数是sockaddr,而不是sockaddr_in和sockaddr_un

  • sockaddr_in和sockaddr_un结构体中前16比特位(前两个字节)分别代表是网络通信还是本地通信
  • 我们在使用socket接口时,根据通信类型选择sockaddr_in和sockaddr_un这两种结构体,需要对结构体内的字段进行填充,传参给sockaddr时必须要进行强制类型转换
  • 在socket函数的内部,对传进来的参数 sockaddr 直接去前两个字节,判断是网络通信还是本地通信, 后再强制类型转换回 sockaddr_in 和 sockaddr_un结构体

传不同的结构体,用相同的参数来接受,在函数内部自动进行区分,这是用C语言实现多态的一种做法

在这里插入图片描述

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

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

相关文章

.NET6.0 System.Drawing.Common 通用解决办法

最近有不少小伙伴在升级 .NET 6 时遇到了 System.Drawing.Common 的问题&#xff0c;同时很多库的依赖还都是 System.Drawing.Common &#xff0c;而 .NET 6 默认情况下只在 Windows 上支持使用&#xff0c;Linux 上默认不支持这就导致在 Linux 环境上使用会有问题&#xff0c;…

低代码解放生产力,助力企业高效发展

近年来&#xff0c;随着数字化转型的推进&#xff0c;企业对于软件开发的需求日益显著。然而&#xff0c;传统的软件开发模式通常需要耗费大量时间和资源&#xff0c;限制了企业的快速响应能力。为了解决这一难题&#xff0c;低代码开发平台应运而生&#xff0c;成为企业和开发…

【沁恒蓝牙mesh】CH58x串口环形FIFO数据处理

本文章主要针对沁恒科技的CH58x芯片&#xff0c;以 BLE_UART 工程为依托&#xff0c;介绍串口数据的接收与处理。 该工程中 串口数据的处理用到了环形FIFO机制&#xff0c;可作为其他开发工具 &#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我…

C++信息学奥赛1130:找第一个只出现一次的字符

这段代码的功能是找出输入字符串中第一个重复出现的字符&#xff0c;并输出该字符。 解析注释后的代码如下&#xff1a; #include<bits/stdc.h> using namespace std; int main() {string arr;getline(cin, arr); int a0;for(int i0;i<arr.length();i){for(int j0;j…

OpenEuler 卸载mysql

查询系统是否安装了MySQL rpm -qa | grep -i mysql 关闭mysql 查看MySQL服务运行状态 ps -ef | grep mysql 或者 service mysql status 没有启动 查看rpm包安装的mysql rpm -qa | grep -i mysql 将这些都卸载了 rpm -e mysql5-server rpm -e mysql5-errmsg rpm -e my…

PAT 1114 Family Property

个人学习记录&#xff0c;代码难免不尽人意 Sample Input: 10 6666 5551 5552 1 7777 1 100 1234 5678 9012 1 0002 2 300 8888 -1 -1 0 1 1000 2468 0001 0004 1 2222 1 500 7777 6666 -1 0 2 300 3721 -1 -1 1 2333 2 150 9012 -1 -1 3 1236 1235 1234 1 100 1235 5678 9012 …

【consul】

consul 一、什么是服务注册与发现1.11.2 二、 什么是consul2.1定义2.2特性2.2.1服务注册与发现&#xff1a;2.2.2健康检查&#xff1a;2.2.3Key/Value存储&#xff1a; 三、consul部署-datacenter &#xff1a;指定数据中心名称&#xff0c;默认是dc1。consul &#xff1a;指定…

leetcode做题笔记86分隔链表

给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 示例 1&#xff1a; 输入&#xff1a;head [1,4,3,2,5,2], x 3 输出&am…

文件四剑客

目录 前言 一、正则表达式 二、grep 三、find 四、sed 五、awk 前言 文件四剑客是指在计算机领域中常用的四个命令行工具&#xff0c;包括awk、find、grep和sed。它们在处理文本文件和搜索文件时非常强大和实用。 1. awk是一种强大的文本处理工具&#xff0c;它允许用户根据指…

【前端】深入理解CSS盒子模型与浮动

目录 一、前言二、盒子模型1、盒子模型组成1.1、border边框1.1.1、边框的三部分组成1.1.2、边框复合简写1.1.3、边框分开写1.1.4、表格的细线边框 1.2、padding内边距1.3、margin外边距1.3.1、外边距水平居中1.3.2、外边距合并1.3.3、嵌套块元素垂直 外边距的塌陷1.3.3.1、解决…

设计模式之门面模式(Facade)的C++实现

1、门面模式提出 在组件的开发过程中&#xff0c;某些接口之间的依赖是比较紧密的&#xff0c;如果某个接口发生变化&#xff0c;其他的接口也会跟着发生变化&#xff0c;这样的代码违背了代码的设计原则。门面设计模式是在外部客户程序和系统程序之间添加了一层中间接口&…

Unity脚本常用生命周期

Unity脚本在Unity引擎运行时会经历多个阶段的变化。如创建&#xff0c;初始化&#xff0c;按帧执行&#xff0c;固定执行&#xff0c;绘制&#xff0c;禁用&#xff0c;销毁等等。具体如下图所示&#xff1a; 我们创建脚本时都是默认继承了MonoBehaviour类&#xff0c;而MonoBe…

【算法系列篇】二分查找——这还是你所知道的二分查找算法吗?

文章目录 前言什么是二分查找算法1.二分查找1.1 题目要求1.2 做题思路1.3 Java代码实现 2.在排序数组中查找元素的第一个和最后一个位置2.1 题目要求2.2 做题思路2.3 Java代码实现 3.搜索插入位置3.1 题目要求3.2 做题思路3.3 Java代码实现 4.x的平方根4.1 题目要求4.2 做题思路…

SpringMVC 反射型跨站点脚本攻击

解决方案&#xff1a; 服务端校验&#xff0c;添加拦截器 配置web,xml <filter><filter-name>xssFilter </filter-name><filter-class>com.fh.filter.XssFilter </filter-class></filter> XssFilter package com.fh.filter;import com…

TikTok Shop内容规则更新,禁止达人进行多平台联播

01.TikTok Shop禁止达人进行多平台联播 TikTok Shop更新了《TikTok Shop内容规则》&#xff0c;公告显示&#xff0c;TikTok Shop高度重视平台用户的安全&#xff0c;为保障用户体验并保护买家免受潜在的误导性广告的影响&#xff0c;在电商直播活动中&#xff0c;达人不得同时…

0基础入门C++之类和对象上篇

目录 1.面向过程和面向对象初步认识2.类的引入3.类的定义3.1类的两种定义方式:3.2成员变量命名规则的建议 4.类的访问限定符及封装4.1访问限定符4.2封装 5.类的作用域6.类的实例化7.类对象模型7.1如何计算类对象的大小7.2 类对象的存储方式猜测 8.this指针8.1this指针的引出8.2…

使用qsqlmysql操作mysql提示Driver not loaded

环境: win10 IDE: qt creator 编译器: mingw32 这里简单的记录下。我遇到的情况是在IDE使用debug和release程序都是运行正常&#xff0c;但是当我编译成发布版本之后。老是提示Driver not load。 这就很奇诡了。 回顾了下编译的时候是需要在使用qt先编译下libqsqlmysql.dll的…

16.遍历二叉树,线索二叉树

目录 一. 遍历二叉树 &#xff08;1&#xff09;三种遍历方式 &#xff08;2&#xff09;递归遍历算法 &#xff08;3&#xff09;非递归遍历算法 &#xff08;4&#xff09;层次遍历算法 二. 基于递归遍历算法的二叉树有关算法 &#xff08;1&#xff09;二叉树的建立 …

交叉编译liblzma:64位版本

xmlIO.c:40:10: 致命错误&#xff1a; lzma.h&#xff1a;没有那个文件或目录40 | #include <lzma.h>在交叉编译libxml时&#xff0c;报错 为解决这个问题&#xff0c;编译liblzma 网址https://tukaani.org/xz/ 解压&#xff1a; tar jxvf xz-5.2.12.tar.bz2执行&#…

Docker(一) 安装Docker

一、安装 安装前置条件 yum install -y yum-utils device-mapper-persistent-data lvm2 更换数据源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 1、指定版本安装 yum list docker-ce --showduplicates | sort -r yum …