socket介绍

socket简介

  • 我们知道两个进程如果需要进行通讯最基本的一个前提能能够唯一的标示一个进程,在本地进程通讯中我们可以使用PID来唯一标示一个进程,但PID只在本地唯一,网络中的两个进程PID冲突几率很大,这时候我们需要另辟它径了,我们知道IP层的ip地址可以唯一标示主机,而TCP层协议和端口号可以唯一标示主机的一个进程,这样我们可以利用ip地址+协议+端口号唯一标示网络中的一个进程。

  • 能够唯一标示网络中的进程后,它们就可以利用socket进行通信了,什么是socket呢?

  • 我们经常把socket翻译为套接字,socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。

  • socket起源于UNIX,在Unix一切皆文件哲学的思想下,socket是一种"打开—读/写—关闭"模式的实现,服务器和客户端各自维护一个"文件",在建立连接打开后,可以向自己文件写入内容供对方读取或者读取对方内容,通讯结束时关闭文件。

【1】什么是socket

  • Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。

  • 在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面

    对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

  • 所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。

  • 也有人将socket说成ip+port

    • ip是用来标识互联网中的一台主机的位置

    • 而port是用来标识这台机器上的一个应用程序

    • ip地址是配置到网卡上的

    • 而port是应用程序开启的

    • ip与port的绑定就标识了互联网中独一无二的一个应用程序

  • 而程序的pid是同一台机器上不同进程或者线程的标识

【2】套接字发展史及分类

  • 套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,即人们所说的 BSD Unix。

  • 因此,有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。

  • 一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。

  • 这也被称进程间通讯,或 IPC。套接字有两种(或者称为有两个种族),分别是

    • 基于文件型的

    • 基于网络型的

(1)基于文件类型的套接字家族

  • 套接字家族的名字:

    • AF_UNIX

  • unix一切皆文件

    • 基于文件的套接字调用的就是底层的文件系统来取数据

    • 两个套接字进程运行在同一机器

    • 可以通过访问同一个文件系统间接完成通信

(2)基于网络类型的套接字家族

  • 套接字家族的名字:

    • AF_INET

  • (还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现

    • 所有地址家族中,AF_INET是使用最广泛的一个

    • python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)

【3】套接字工作流程

(1)流程分析(打电话)

# (1)打电话
# 一部手机
# 一张电话卡 : 用来表是哪个号是你本人的
# 拨打电话:
# 和打出去的电话的人建立联系
# 和对方进行交流
# 挂断电话
# (2)接电话
# 一部手机
# 一张电话卡 : 用来表是哪个号是你本人的
# 接听电话
# 和打进来的电话的人建立联系
# 和对方进行交流
# 挂断电话

(2)流程分析

# (1)接电话 --- 服务端
# 一部手机:初始化 socket 对象
# 一张电话卡 :与本地的端口进行绑定
# 拨打电话:listen 监听当前是否有人接通电话
# 和打出去的电话的人建立联系 : accept 接收到客户端连接 进行阻塞 connect 连接
# 和对方进行交流 :send 发送信息
# 挂断电话 close
# (2)接电话 --- 客户端
# 一部手机 : 初始化 socket 对象
# 一张电话卡 :与本地的端口进行绑定
# 接听电话 : connct
# 和打进来的电话的人建立联系  connect 连接
# 和对方进行交流 : send 发送信息
# 挂断电话 close

(3)代码分析

import socket
​
# (1)接电话 --- 服务端
# 一部手机:初始化 socket 对象
# family=-1 : AF_INET
# type=-1 : SOCK_STREAM  --- 基于TCP的流式协议
# proto=-1 :  0
# 初始化 socket 对象 : 获得到一个基于TCP的流式协议的TCP对象
server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
​
# 一张电话卡 :与本地的端口进行绑定
ip = '127.0.0.1'
port = 9000
server.bind((ip, port))
​
# 拨打电话:listen 监听当前是否有人接通电话
# 半连接池
server.listen(5)
​
# 和打出去的电话的人建立联系 : accept 接收到客户端连接 进行阻塞 connect 连接
conn, addr = server.accept()
# 只能发送二进制数据
data = ''
conn.send(data.encode())
​
# 和对方进行交流 :send 发送信息
data = conn.recv(1024)  # 1kb = 1024字节
print(data.decode())
# 挂断电话 close
conn.close()
server.close()
# (2)接电话 --- 客户端
# 一部手机 : 初始化 socket 对象
client = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
# 一张电话卡 :与本地的端口进行绑定
ip = '127.0.0.1'
port = 9000
client.connect((ip, port))
# 接听电话 : connct
# 和打进来的电话的人建立联系  connect 连接
data = client.recv(1024)
print(data.decode())
# 和对方进行交流 : send 发送信息
​
data = ''
client.send(data.encode())
# 挂断电话 close
client.close()

【4】代码初识

(1)服务端

import socket
​
# (1)接电话 --- 服务端
# 一部手机:初始化 socket 对象
# family=-1 : AF_INET
# type=-1 : SOCK_STREAM  --- 基于TCP的流式协议
# proto=-1 :  0
# 初始化 socket 对象 : 获得到一个基于TCP的流式协议的TCP对象
server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
​
# 一张电话卡 :与本地的端口进行绑定
ip = '127.0.0.1'
port = 8001
server.bind((ip, port))
​
# 拨打电话:listen 监听当前是否有人接通电话
# 半连接池
server.listen(5)
​
# 和打出去的电话的人建立联系 : accept 接收到客户端连接 进行阻塞 connect 连接
conn, addr = server.accept()
# 只能发送二进制数据
from_server_to_client_send_data = f'我是来自服务端的一条数据'
conn.send(from_server_to_client_send_data.encode())
​
# 和对方进行交流 :send 发送信息
from_client_to_server_recv_data = conn.recv(1024)  # 1kb = 1024字节
print(from_client_to_server_recv_data.decode())
# 挂断电话 close
conn.close()
​
server.close()

(2)客户端

import socket
​
# (2)接电话 --- 客户端
# 一部手机 : 初始化 socket 对象
client = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
# 一张电话卡 :与本地的端口进行绑定
ip = '127.0.0.1'
port = 8001
client.connect((ip, port))
# 接听电话 : connct
# 和打进来的电话的人建立联系  connect 连接
from_server_to_client_recv_data = client.recv(1024)
print(from_server_to_client_recv_data.decode())
# 和对方进行交流 : send 发送信息
​
from_client_to_server_send_data = '我是来自客户端的一条数据'
client.send(from_client_to_server_send_data.encode())
# 挂断电话 close
client.close()

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

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

相关文章

pytest教程-46-钩子函数-pytest_sessionstart

领取资料,咨询答疑,请➕wei: June__Go 上一小节我们学习了pytest_report_testitemFinished钩子函数的使用方法,本小节我们讲解一下pytest_sessionstart钩子函数的使用方法。 pytest_sessionstart 是 Pytest 提供的一个钩子函数&#xff0c…

JSON对象相互转换

目录 String --> JsonNode对象 JsonNode对象 --> String Map --> JsonNode对象,object> JsonNode数组 --> List>集合 List> --> JsonNode 获取JsonNode中某个key的值 获取JsonNode字段下的某个数组 String --> JsonNode对象 // 创建一个 Ob…

Anaconda下载安装

看到这篇文章的同学们,说明你们是要下载Anaconda,这篇文章讲的就是下载安装教程。 Anaconda下载网址: Download Now | Anaconda 根据我们需要的系统版本下载,我的电脑是window,所以选择第一个,如下图&am…

javaEE进阶——SpringBoot与SpringMVC第一讲

文章目录 什么是springMVCSpringMVC什么是模型、视图、控制器MVC和SpringMVC的关系SpringMVC的使用第一个SpringMVC程序RestController什么是注解 那么RestController到底是干嘛的呢?RequestMapping 如何接收来自请求中的querystryingRequestParamRequestMapping(&q…

运用MongoDB Atlas释放开发者潜能同时把控成本

在当下的商业环境中,不可预测性已经成为常态,工程团队负责人必须在把控不可预测性和优化IT成本的双重挑战下谋求平衡。 咨询公司德勤2024 MarginPLUS调查收集了300多位企业负责人的见解,报告中重点介绍了面对动荡的全球经济环境,…

电子邮箱是什么?付费电子邮箱和免费电子邮箱有什么区别?

注册电子邮箱前,有付费电子邮箱和免费电子邮箱两类选择。付费的电子邮箱和免费的电子邮箱有什么区别呢?区别主要在于存储空间、功能丰富度和售后服务等方面,本文将为您详细介绍。 一、电子邮箱是什么? 电子邮箱就是线上的邮局&a…

labelimg删除用不到的标签(yolo格式)以及 下载使用

问题:当我们标注完成新的类别后后直接删除classes.txt中不需要的类别之后再次打开labelimg会闪退,如何删除不需要的标签并且能够正确运行呢?(yolo格式) 原因:当我们打开labelimg进行标注的时候&#xff0c…

LVM - Linux磁盘逻辑卷管理器概念讲解、实践及所遇到的问题

1、lvm概念 逻辑卷管理器(LogicalVolumeManager)本质上是一个虚拟设备驱动,是在内核中块设备和物理设备之间添加的一个新的抽象层次,它可以将几块磁盘(物理卷,PhysicalVolume)组合起来形成一个存储池或者卷组(VolumeGroup)。LVM可以每次从卷组中划分出不同大小的逻辑卷(Logi…

【C语言】必备Linux命令和C语言基础

🌟博主主页:我是一只海绵派大星 📚专栏分类:嵌入式笔记 ❤️感谢大家点赞👍收藏⭐评论✍️ 目录 一、文件和目录相关命令 Linux 的文件系统结构 文件系统层次结构标准FHS pwd命令 ls 列目录内容 文件的权限 c…

STC8增强型单片机开发【热敏电阻】

目录 一、引言 二、热敏电阻概述 三、STC8增强型单片机简介 四、基于STC8单片机的热敏电阻测温系统 五、热敏电阻测温系统的优化与扩展 提高测量精度 扩展系统功能 六、 温度计算步骤 通过ADC采样计算出热敏电阻位置的电压 通过欧姆定律计算热敏电阻的阻值 通过阻值…

Java中成员变量与局部变量的区别?

在Java中,成员变量和局部变量是两种不同类型的变量,它们有不同的作用范围和特性。理解它们之间的区别对于编写高效、清晰的代码至关重要,区别: 1. 语法形式 成员变量: 定义在类内部但在方法外部。可以使用public、p…

栈和队列经典面试题详解

目录 题目一:20. 有效的括号 - 力扣(LeetCode) 题目二:225. 用队列实现栈 - 力扣(LeetCode) 题目三:232. 用栈实现队列 - 力扣(LeetCode) 题目四:622. 设…

软件压力测试怎么做

随着信息技术的迅猛发展,软件在各行各业的应用越来越广泛,其稳定性、可靠性和性能表现也受到了越来越多的关注。在这样的背景下,软件压力测试显得尤为重要。本文将详细介绍软件压力测试的概念、目的、方法以及实施步骤,帮助读者更…

浅析扩散模型与图像生成【应用篇】(二十五)——Plug-and-Play

25. Plug-and-Play: Diffusion Features for Text-Driven Image-to-Image Translation 该文提出一种文本驱动的图像转换方法,输入一张图像和一个目标文本描述,按照文本描述对输入图像进行转换,得到目标图像。图像转换任务其实本质上属于图像编…

对于接口的安全性测试,这几点你掌握了吗?

接口防刷 1.为什么会有人要刷接口? 牟利:黄牛在 12306 网上抢票再倒卖。 恶意攻击竞争对手:如短信接口被请求一次,会触发几分钱的运营商费用,当量级大了也很可观。 压测:用apache bench 做压力测试。 …

管仲故乡是颍川,何分颍上或颍下

第一仲父管仲,故乡在哪里?依然像许多名人故里一样存在争议,但是这个争议却很不一般,引出了一个大话题。 管子是安徽颍上县人,《史记》记载: “管仲,颍上人也。”颍上县有管鲍祠,是安徽省重点文物…

Go并发编程机制

目录 1. 并发编程基础概念 1.1 什么是并发编程 1.2 并发与并行区别 1.3 为什么需要并发编程 1.4 Go语言并发优势 2. Go语言并发机制 2.1 Goroutine轻量级线程 2.2 Channel通信机制 2.3 WaitGroup等待组 2.4 Mutex互斥锁与读写锁 3. 并发模式与实践 3.1 Fan-in模式 …

亚阈值电流镜

相同电流情况下,由于亚阈值区的gm较大,造成由于阈值电压Vth的失配造成的失配会更大,所以要规避过大的gm,选取较大的过驱动电压。 相同电流情况下,W/L的尺寸选的较小一点,或者说L一定时,W不要取得过大。 Q:Vgs一定的情况下,特别小,几乎小于Vth,一定是亚阈值电流镜吗。…

第10章:新建MDK工程-寄存器版

0. 《STM32单片机自学教程》专栏 本文作为专栏《STM32单片机自学教程》专栏其中的一部分,返回专栏总纲,阅读所有文章,点击Link: STM32单片机自学教程-[目录总纲]_stm32 学习-CSDN博客

Leetcode 513:找树左下角的值

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 思路:层次遍历 每次遍历一层时,记录下每层的最左侧元素,当结束层次遍历时,记录的就是所求结果。 public s…