计算机网络(二) —— 网络编程套接字

news2024/12/26 23:24:37

目录

一,认识端口号

1.1 背景

1.2 端口号是什么

1.3 三个问题

二,认识Tcp协议和Udp协议

三,网络字节序

四,socket编程接口

4.1 socket常见API

4.2 sockaddr结构


一,认识端口号

1.1 背景

问题:在进行网络通信的时候,是不是我们的的两台机器在通信呢?

解答:我们把软件下载下来安装好,但是不打开,不耗费流量;只有当我们打开,它加载的时候才会耗流量。所以,网络通信的时候,本质是应用层在通信

  •  网络协议的下三层:网络层,传输层,数据链路层,主要解决数据安全可靠地被送到远端机器
  • 用户使用应用层软件,完成数据地发送和接收,而软件要进行通信就要先启动起来,而启动一个软件也就是进程创建
  • 所以日常我们网络通信的本质:就是“进程间通信”,两个进程间要通信就是让两个进程看到同一份资源,这个资源就是网络,而这个网络再具体一点就是网络协议栈

问题: 当传输层即将把数据交给应用层时,但是此时应用层有很多应用,它咋知道要把数据交给哪个应用呢?

解答:所以上层要和传输层达成一种方案,让数据能够准确地交给上层,这个方案叫做“端口号”

1.2 端口号是什么

端口号:是传输层协议的内容,是一个2字节16位的整数,就是4个数字,它用来标识一个进程,告诉操作系统,当前这个数据从传输层要交给应用层的哪一个应用

  • 端口号无论对于客户端还是服务器,都能唯一地标识该主机上的一个网络应用层的进程,这点类似于进程的PID,一个端口号只能被一个进程占用
  • 在公网上,ip地址能表示唯一的一台主机,端口号(port),用来标识该主机上的唯一一个进程,所以 ip + port = 标识全网唯一的一个进程
  • 所以客户端和服务器都要有自己的ip和port,这种基于ip + port 的通信方式,我们叫做socket,后面会讲

1.3 三个问题

问题:端口号和我们的进程pid有什么区别,两者似乎都能标识该主机上进程的唯一性,那为什么不用pid要用端口号?

解答

  • 不是所有的进程都需要网络通信,但是所有进程都要有pid --> 告诉我们网络是需要单独设计的
  • 实现端口号,是为了实现系统和网络的功能解耦,因为系统可能会变,当两者分开设计后,一方收影响就不会影响对方或者对对方的影响大大降低

问题:服务器和客户端是如何知道对方的端口号的?

解答

首先是客户端如何知道服务器端口号的:

  • 服务器和端口号都是同一家公司开发的,所以要想客户端知道端口号,那么这个端口号必须是众所周知的,精心设计的被客户端知晓的
  • 这个一般由开发商做的,安装的时候将端口号或者ip直接内置进去了

然后是服务器如何知道客户端端口号的:

  • 每次请求都是客户端主动发起的,所以让服务器知道客户端端口号是比较容易的

问题:传输层是如何根据端口号讲数据准确交给应用层众多进程中的那一个对应进程的?

解答

  • 操作系统会在传输层给我们形成一张哈希表,里面存的都是各个进程PCB的指针
  • 首先进程绑定端口号的时候,就根据哈希算法找到对应位置,如果这个位置没有PCB指针,就把该进程的PCB指针存进去,当把PCB指针放进哈希表时,就可以认为该进程绑定了端口号
  • 然后客户端的报文到了服务器的传输层时,传输层就拿着报文中的端口号在哈希表里做哈希运算,找到哈希表对应位置的进程PCB指针,进而找到对应进程,完成传输层将数据交给应用层的某个具体进程
  • 一个进程可以绑定多个端口号,但是一个端口号只能绑定一个进程,因为哈希表是这样规定的,比如哈希表多个位置可以放同一个指针,但是同一个位置只能放一个指针

二,认识Tcp协议和Udp协议

网络协议栈是贯穿整个体系结构的,在操作系统层,应用层和驱动层都有自己的协议。而离我们普通程序员最近的就是使用系统调用接口实现网络通信了,所以离我们最近的就是传输层,传输层应用最广泛最受欢迎的两种协议就是TCP协议UDP协议

TCP协议

Tcp:传输控制协议(Transmission Control Protocol),是一种面向连接的,可靠的,基于字节流的传输层协议。

  • 如果两台主机想通过Tcp进行数据通信,那么必须先建立好连接道路,并确保建立成功后才进行数据传输
  • 同时,Tcp协议也是保证数据传输可靠的协议,数据在传输过程中如果出现了丢包,乱序等情况,Tcp协议都有对应的解决方法,具体我们后面再讲

UDP协议

 UDP:用户数据报协议(User Datagram Protocol),是一种无需建立连接,不可靠的,面向数据报的传输层协议

  • 如果两台主机要使用Udp通信,无需建立连接,一方根据IP和端口直接就将数据发送给对方,这也就意味着Udp协议是不可靠的,中途出现丢包,乱序等情况,Udp都不会去处理

问题:Tcp比Udp可靠,那为啥传输层要这两种协议同时存在呢?

解答: 

  • 其实这里的“可靠”和“不可靠”都是中性词,无褒贬含义,就和化学里的“惰性”一样,只是描述某个东西的物理特征,并不是说这个物理懒之类的
  • 保证可靠是需要成本的,而相反,不可靠相反的就是简单,TCP在比如说银行转账,微信支付的时候,底层必须是TCP协议,而UDP通常在直播,信息流视频流做数据大量派发的场景有用
  • TCP虽然是可靠传输,但并不是万能的,它是保证在网络连通且链接较强的时候处理一些数据丢失问题,也就意味着Tcp的传输效率是没Udp高的,Tcp会在底层做更多的工作

三,网络字节序

计算机在存储数据时是有大小端的概念的:

  • 大端:数据的高字节内容保存在内存的低地址处,低字节保存在内存的高字节处
  • 小端:数据的低字节内容保存在内存的低地址处,高字节保存在内存的高字节处

如果编写的程序只在本地机器上运行,那么是不需要考虑大小端转换的问题的;但是到了网络通信时,是两台主机在进行进程间通信了,那么这两台主机采用的存储方式可能不一样,比如大端机器传数据给小端机器,那么小端机器解析出来的数据就和大端机器是不一样的

所以我们解决上面的问题,为此:TCP/IP 协议 规定,网络数据流都要采用大端字节序:

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

注意:所有的大小端的转化工作由操作系统来完成,因为该操作属于通信细节,不过也有部分的数据需要我们自行进行处理,比如IP的端口号

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

#include<arpa/inet.h>

uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntonl(uint32_t netlong);
uint16_t ntons(uint16_t netshort);
  • h表示host,n表示network,l表示32位长整数,s表示16位短整数。
  • 例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
  • 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回。
  • 如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。

四,socket编程接口

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

4.2 sockaddr结构

可以发现,上面的每个接口的参数都有一个结构体指针 struct sockaddr* addr,下面详细介绍一下:

套接字有三种:

  • 1,域间套接字编程:套接字不仅支持跨网络的进程间通信,也支持本地的进程间通信,用的就是这个
  • 2,原始套接字编程:通常用来编写一些网络工具,比如监测,抓包等
  • 3,网络套接字编程:重点使用传输层,通过TCP和UDP实现用户间的网络通信

所以最开始的套接字结构体提供了两种:

  • sockaddr_un:用于本地
  • sockaddr_in:用于跨网络

 套接字种类不同,就有不同的应用场景,但是网络接口的设计者不想搞三套,计划将网络接口统一抽象化;而网络接口要想统一,那么接口的参数类型必须一致,所以就设计了sockaddr这个结构体:

  • 之后在传参数的时候只要传sockaddr这一个就可以了,在设置参数之前就可以往这个结构体添加字段,这点下一篇简单Udp和程序的代码中会具体表现
  • 如上图,在调用socket API 的那些接口时,这些API就可以提取 sockaddr 内部的头16字节进行识别,进而得出我们是要进行网络通信还是本地通信,执行对应的操作,完成接口的统一
  • 注意:实际在进行网络通信时,定义的还是 sockaddr_in 这样的结构体,只是在传参的时候将该结构体的地址类型强制转换位 sockaddr* 罢了 

问题:为啥不用C语言的万能参数 void* 来代替struct sockaddr* 类型呢? 

解答:最简单的原因就是,设计网络接口时,C语言还不支持void*传参,而在后面C语言支持void*之后,也很难改回来了,因为这些接口都是系统接口,而系统接口是上层软件接口的基石,所以系统接口不是想改就改的,所以现在的网络接口依旧保留了sockaddr

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

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

相关文章

C++,Qt学习 2024.9.10

制作ui界面实现&#xff1a;模拟定时闹钟功能 启动后&#xff0c;lab实时获取系统时间&#xff0c;当系统时间走到设置的时间时&#xff0c;语音播报下方lineEdit中的内容&#xff0c;启动前取消按键不可用&#xff0c;启动后除了取消按键可用其他部分都设为不可用&#xff0c…

Java 创建对象方法的演变

1、普通 Java 代码 public class Rectangle {private int width;private int length;public Rectangle() {System.out.println("Hello World!");}public void setWidth(int widTth) {this.width widTth;}public void setLength(int length) {this.length length;}…

个人随想-如何开发一个code agent

随着sonnet的普及&#xff0c;现在的开发确实可以达到事半功倍的效果&#xff0c;再加上cursor、claude dev等工具的加持&#xff0c;现在的软件开发&#xff0c;确实门槛降低了很多&#xff0c;我们可以快速的让ai给我们大量的提示、重构、单元测试、explain甚至是完全用自然语…

c++指针和引用专题

一 基本概念 图解C++指针与引用的区别_指针与引用 图解-CSDN博客https://blog.csdn.net/shang_0122/article/details/104755481 为什么C+

房屋租赁|基于springboot的房屋租赁管理系统设计与实现(附项目源码+论文+数据库)

私信或留言即免费送开题报告和任务书&#xff08;可指定任意题目&#xff09; 目录 一、摘要 二、相关技术 三、系统设计 四、数据库设计 五、核心代码 六、论文参考 七、源码获取 一、摘要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#x…

方位对称性+均匀分布=交叉极化和同极化不相关

这个推导是一种方为对称散射矩阵的均匀分布&#xff0c;对于多种方位对称性的散射矩阵&#xff0c;均匀分布。可以看作该模型的简单叠加。从而交叉极化和同极化不相关

PhotoZoom Classic 9.0.2中文版新功能介绍及PhotoZoom 9使用教程

PhotoZoom Classic 9.0.2中文版简介 PhotoZoom Classic 9.0.2中文版是一款新颖的、技术上具有革命性的对数码图片进行放大的工具。通常的工具对数码图片进行放大时&#xff0c;总会降低图片的品质&#xff0c;而这款软件使用了S-SPLINE技术(一种申请过专利的&#xff0c;拥有自…

Word文档的读入(3)

逐个读取答题卡后&#xff0c;我们可以访问Word文档&#xff08;Document&#xff09;中的 .paragraphs 属性&#xff0c;来获取文档中的段落列表。段落列表的组成元素是所有的段落对象&#xff0c;可以使用索引定位到指定的段落对象。 完善代码&#xff08;读取学生学号所在的…

FFmpeg 7.0 版本 “Dijkstra”的特点概述

FFmpeg 7.0 FFmpeg 官网:https://ffmpeg.org/FFmpeg 官网更新日志,2024.4.5 号发布代号"Dijkstra"的 7.0 版本的 FFmpeg,如下截图: 为什么叫 Dijkstra“Dijkstra” 指的是艾兹格戴克斯特拉(Edsger Wybe Dijkstra),他是一位荷兰计算机科学家,对计算机科学领域…

为什么Java已经不推荐使用Stack了?

为什么不推荐使用Stack Java已不推荐使用Stack&#xff0c;而是推荐使用更高效的ArrayDeque 为什么不推荐使用 性能低&#xff1a;是因为 Stack 继承自 Vector&#xff0c; 而 Vector 在每个方法中都加了锁。由于需要兼容老的项目&#xff0c;很难在原有的基础上进行优化&…

多目标优化算法求解WFG(Walking Fish Group)测试函数

WFG&#xff08;Walking Fish Group&#xff09;测试函数套件是一组用于多目标优化的基准测试问题&#xff0c;由Simon Huband, Luigi Barone, Lyndon While和Phil Hingston提出。这些测试问题旨在提供一个全面的测试平台&#xff0c;以评估多目标优化算法的性能。WFG测试集包含…

操作系统 --- 线程(Threads)概念 多线程模型 线程控制与组织

零、学习路线 一、线程的引入&#xff0c;什么是线程&#xff0c;为什么要引入线程&#xff1f; 如果说&#xff0c;在OS中引入进程的目的是为了使多个程序能并发执行&#xff0c;以提高资源利用率和系统吞吐量&#xff0c;那么&#xff0c;在操作系统中再引入线程&#xff0c…

[网鼎杯 2020 朱雀组]Nmap 历程记录

分析&#xff1a;根据题目名称知道本题肯定会涉及nmap的使用&#xff0c;访问web页面 扫描自己,发现没啥有用的信息&#xff0c;他这里每扫一个主机会把扫描信息存在一个新的文件里&#xff0c;简单试了一下传的参数&#xff0c;也没发现sql注入 这个地方提供的参数会被nmap去拼…

新版idea java_home报错 以及markdown插件无法使用

报错&#xff1a;The environment variable JAVA_HOME(with the value of does not point to a valid JVM&#xff09; 1.检查java环境发现换成jdk8 或者jdk17 都没有问题&#xff0c;但是idea还是报错 可能是由于idea界面采用新技术JCEF缺少环境&#xff0c;我的idea版本是20…

从腾讯大模型的「实用」路线,我们看到了企业应用AI的新方向

「现在每家公司都是 AI 公司&#xff0c;但引入 AI 之后&#xff0c;利润真的能提高吗&#xff1f;」 在针对 Transformer 作者、Cohere CEO Aidan Gomez 的一次采访中&#xff0c;播客主持人 Harry Stebbings 问出了这样一个问题。 Stebbings 提到&#xff0c;现在很多公司都…

赎金信--力扣383

赎金信 题目思路一方法一&#xff1a;哈希表思路二方法二 数组 题目 思路一 我们使用哈希表map的思路&#xff0c;A能不能由B组成&#xff0c;说明B包含的元素个数要大于等于A。 所以我们先利用map的key和value分别对magazine中的出现的字符以及出现的次数存储起来。 然后我们…

力扣题解2552

大家好&#xff0c;欢迎来到无限大的频道。 今天和大家分享的是2552的题解思路。 题目描述&#xff1a; 统计上升四元组 一个长度为 n 下标从 0 开始的整数数组 nums &#xff0c;它包含 1 到 n 的所有数字&#xff0c;请你返回上升四元组的数目。 如果一个四元组 (i, j, …

RocketMQ异步报错:No route info of this topic

在SpringBoot中发送RocketMQ异步消息的时候报错了&#xff0c;提示org.apache.rocketmq.client.exception.MQClientException: No route info of this topic, testTopic1 这里给出具体的解决方案 一、Broker模块不支持自动创建topic&#xff0c;并且topic没有被手动创建过 R…

智慧教室无纸化方案应用领域和技术实践探究

智慧教室无纸化应用场景 智慧教室无纸化方案在多个领域得到了广泛应用&#xff0c;主要体现在教育领域&#xff0c;但随着技术的发展和应用的深入&#xff0c;其应用范围也在逐渐扩大。以下是一些主要的应用领域&#xff1a; 一、教育领域 课堂教学&#xff1a; 中小学数学课…

BFS迷宫最小路径问题

给定一个迷宫&#xff0c;0表示空地可以走&#xff0c;1表示墙壁不能穿越&#xff1b;在迷宫中可以向&#xff08;上下左右&#xff09;四个方向行进&#xff1b; 找到从左上角到右下角的最短路径&#xff0c;并计算最短路径的长度。 迷宫示例如下&#xff1a; 算法步骤&…