Python 笔记02 (网络交互 TCP/UDP)

一 socket网络及差别介绍

TCP(传输控制协议)和UDP(用户数据报协议)是两种常见的互联网传输协议,它们之间有很多区别,包括以下几个主要方面:

1.1 TCP

TCP是传输控制协议,是面向连接的通讯协议(如:打电话),通过三次握手建立连接,通讯完成时四次挥手,一般应用在对安全性、完整性有严格要求的场景,如FTP、SMTP、HTTP等

  1. 优点:TCP 具有高可靠性,确保传输数据的正确性,不出现丢失或乱序
  2. 缺点:TCP相对于UDP速度慢一点,效率低,而且要求系统资源较多,每个连接都会占用系统的CPU、内存等硬件资源

1.2 UDP

UDP是用户数据报协议,是面向无连接的通讯协议(如:发短信)

  1. 优点:UDP速度快、操作简单、要求系统资源较少
  2. 缺点:不可靠,可能会出现丢包、乱序、数据不完整

1.3 TCP 与 UDP 的区别:

  1. 连接 TCP 是面向连接的传输层协议,传输数据前先要建立连接UDP 是不需要连接,即刻传输数据。
  2. 服务对象 TCP 是一对一的两点服务,即一条连接只有两个端点。UDP 支持一对一、一对多、多对多的交互通信
  3. 可靠性 TCP 是可靠交付数据的,数据可以无差错、不丢失、不重复、按序到达。UDP 是尽最大努力交付,不保证可靠交付数据。
  4. 拥塞控制、流量控制 TCP 有拥塞控制和流量控制机制,保证数据传输的安全性。UDP 则没有,即使网络非常拥堵了,也不会影响 UDP 的发送速率
  5. 首部开销 TCP 首部长度较长,会有一定的开销,首部在没有使用「选项」字段时是 20 个字节,如果使用了「选项」字段则会变长的。UDP 首部只有 8 个字节,并且是固定不变的,开销较小,对系统资源要求较少。
  6. 实时性 UDP 具有较好的实时性,工作效率比 TCP 协议高。

1.4 应用场景

  1. 由于 TCP 是面向连接,能保证数据 的可靠性交付,因此经常用于:(20/21端口)FTP 文件传输HTTP / HTTPS(80端口) 、SMTP(简单邮件传送协议)、TELNET(远程终端协议)
  2. 由于 UDP 面向无连接,它可以随时发送数据,再加上UDP本身的处理既简单又高效,因此经常用于:包总量较少的通信,如 DNS 、SNMP、TFTP(简单文件传输协议) 等、视频、音频等多媒体通信、广播通信

1.5 Socket数据传输方式

常用的有两种:

  1. SOCK_STREAM:表示面向连接的数据传输方式。数据可以准确无误地到达另一台计算机,如果损坏或丢失,可以重新发送,但效率相对较慢。常见的 http 协议就使用 SOCK_STREAM 传输数据,因为要确保数据的正确性,否则网页不能正常解析。针对于面向连接的TCP服务应用;
  2. SOCK_DGRAM:表示无连接的数据传输方式。计算机只管传输数据,不作数据校验,如果数据在传输中损坏,或者没有到达另一台计算机,是没有办法补救的。也就是说,数据错了就错了,无法重传。因为 SOCK_DGRAM 所做的校验工作少,所以效率比 SOCK_STREAM 高。对应于无连接的 UDP服务应用。

1.6 服务器端

from socket import *
server = socket(AF_INET, SOCK_DGRAM)
server_host_port = ('127.0.0.1', 6000)   # 服务器的IP地址和端口# 接收数据前绑定端口
server.bind(server_host_port)while True:# 接收数据data = server.recvfrom(1024)# print('data:', data)  # (b'\xe4\xbd\xa0\xe5\xa5\xbd', ('127.0.0.1', 61328))print('访问者:', data[0].decode('utf-8'))  # 你好# print(f'客户端的IP:{data[1][0]}  \n客户端的端口:{data[1][1]}')"""重新发送数据"""send_data = input('客服说:')server.sendto(send_data.encode('utf-8'), data[1])# server.close()

1.7 客户端

from socket import *
client = socket(AF_INET, SOCK_DGRAM)
server_host_port = ('127.0.0.1', 6000)   # 指定数据接收方while True:data = input('访问者:')data = data.encode('utf-8')client.sendto(data, server_host_port)   # 发送数据if data.decode('utf-8') == 'bye':break"""接收返回数据数据"""recv_data = client.recvfrom(1024)print(f"客服说:{recv_data[0].decode('utf-8')}")print('程序关闭')
client.close()

二 UDP协议

udp的交互使用:sendto 和 recvfrom

SOCK_DGRAM:表示无连接的数据传输方式。计算机只管传输数据,不作数据校验,如果数据在传输中损坏,或者没有到达另一台计算机,是没有办法补救的。也就是说,数据错了就错了,无法重传。因为 SOCK_DGRAM 所做的校验工作少,所以效率比 SOCK_STREAM 高。对应于无连接的 UDP服务应用。

2.1 服务器代码

from socket import *
import struct
server_socket = socket(AF_INET, SOCK_DGRAM)host_port = ('localhost', 8888)   # 端口号# 开始监听
server_socket.bind(host_port)# 接收数据
data = server_socket.recvfrom(1024)
print(data, type(data))# 解析操作码
recv_data = data[0]
new_data = struct.unpack('!H', recv_data[:2])
print('客户端请求的操作码:', new_data)# 解析文件名
file_name = recv_data[2:-7].decode('utf-8')
print('客户端请求下载的文件名:', file_name)
server_socket.close()

2.2 客户端代码

from socket import *
import struct
client_socket = socket(AF_INET, SOCK_DGRAM)host_port = ('localhost', 8888)   # 端口号file_name = input('请输入需要上传的文件名:').encode('utf-8')
print('file_name:', file_name, len(file_name))
data = struct.pack('!H%dsb5sb' % len(file_name), 1, file_name, 0, 'octet'.encode('utf-8'), 0)# 发送数据
client_socket.sendto(data, host_port)
client_socket.close()

三 TCP协议

tcp的交互使用:send 和 recv

SOCK_STREAM:表示面向连接的数据传输方式。数据可以准确无误地到达另一台计算机,如果损坏或丢失,可以重新发送,但效率相对较慢。常见的 http 协议就使用 SOCK_STREAM 传输数据,因为要确保数据的正确性,否则网页不能正常解析。针对于面向连接的TCP服务应用;

3.1 TCP服务器代码

from socket import *
import random# 创建SOCKET对象
server_socket = socket(AF_INET, SOCK_STREAM)# 绑定IP和端口
host_port = ('', 6666)   # 不写本机所有
server_socket.bind(host_port)# 设置listen
server_socket.listen(5)while True:# 等待客户端连接client_socket, addr = server_socket.accept()print('客户端已连接,3次握手完成! ')# print('client_socket:', client_socket)# 接收数据data = client_socket.recv(1024).decode('utf8')print('data:', data)oper_code = data.split(':')[0]  # 操作码recv_data = data.split(':')[1]  # 需要上传和下载的文件if oper_code == '1':  # 下载操作file_read = open(recv_data, 'r', encoding='utf8')data = file_read.read()# 将数据发给客户端client_socket.send(data.encode('utf-8'))file_read.close()elif oper_code == '2':  # 上传操作file_write = open(str(random.randint(1000, 9999)) + '.txt', 'w', encoding='utf-8')file_write.write(recv_data)file_write.close()print('服务器接收完成!')elif oper_code == '0':  # 已退出print(recv_data)

3.2 客户端代码

from socket import *while True:client_socket = socket(AF_INET, SOCK_STREAM)# 指定要连接的IPhost_port = ('127.0.0.1', 6666)# 开始连接服务器client_socket.connect(host_port)choice = eval(input('请选择操作: 0.退出  1.下载  2.上传  \n'))if choice == 1:file_name = input('请输入要下载的文件名:')# 告诉服务器要下载的文件名join_data = (str(choice) + ':' + file_name).encode('utf-8')# 发送数据client_socket.send(join_data)# 接收服务器返回的数据recv_data = client_socket.recv(1024).decode('utf-8')# 写入本地磁盘download = open(file_name, 'w', encoding='utf-8')download.write(recv_data)download.close()print('下载完成')elif choice == 2:  # 上传path_name = input('请输入要上传的文件名:')# 本地读取upload = open(path_name, 'r', encoding='utf-8')upload_data = upload.read()# 拼接数据结构data = (str(choice) + ':' + upload_data).encode('utf-8')# 向服务器发送数据client_socket.send(data)upload.close()print('数据上传成功!')elif choice == 0:# 告诉服务器已退出client_socket.send((str(choice) + ':' + '客户端已退出').encode('utf-8'))breakprint('客户端关闭')

TCP连接时三次握手

  • 第一次:客户端向服务器端发送连接报文(SYN=1),同时选择一个初始序列号 seq=x,一起发送

  • 第二次:服务器收到报文后向客户端发报文,确认报文为:(ACK=1,SYN=1),确认号为ack=x+1,同时服务器初始化一个序列号:seq=y,一起发送

  • 第三次:客户端向服务器端发送报文(ACK=1),同时发送:ack=x+1,seq=y+1进行确认

TCP断开时四次挥手:开时四次挥手:

  • 第一次:客户端发送释放报文并停止发送数据(FIN=1),带上序列号 seq=u,客户端进入终止等待状态(FIN-WAIT-1)

  • 第二次:服务器收到报文后释放报文,发出确认报文(ACK=1,ack=u+1),并且带上序列号 seq=v,服务器进入关闭等待状态(CLOSE-WAIT)

  • 第三次:服务器在数据传输完毕后发送连接释放报文(FIN=1,ack=u+1),同时发送序列号:seq=w,服务器进入最后确认状态(LAST-ACK)

  • 第四次:客户端收到释放报文后,向服务器发送报文(ACK=1,ack=w+1),发送序列号 seq=u+1,客户端进入时间等待状态(TIME-WAIT)。服务器接收到报文后直接关闭,客户端需要等2**MSL(最长报文段寿命)后结束

四 使用TCP传输较大的文件

4.1 服务端代码

from socket import *
import struct
server_socket = socket(AF_INET, SOCK_STREAM)  # TCPhost_port = ('', 6666)
server_socket.bind(host_port)server_socket.listen(1024)
# 开始监听
conn_socket, addr = server_socket.accept()
print('查看服务器接收到的请求地址:', addr)# 接收数据
data_header = conn_socket.recv(4)
# 解包
size = struct.unpack('!i', data_header)[0]
print('size:', size)# 将收到的数据上传到磁盘
file = open('a.pptx', 'wb')
recv_size = 0
while recv_size < size:data_pack = conn_socket.recv(1024)recv_size += len(data_pack)file.write(data_pack)file.close()
print('服务器接收完成')
conn_socket.close()
server_socket.close()

4.2 客户端代码

from socket import *
import os.path
import structclient_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect(('192.168.146.1', 6666))# 发送内容
file_path = './111.pptx'# 获取文件大小
size = os.path.getsize(file_path)
print('size:', size)# 对struct数据进行打包
data = struct.pack('!i', size)
# 发送数据
client_socket.send(data)file = open(file_path, 'rb')
# 循环读取 1024
while True:data_pack = file.read(1024)if not data_pack:breakclient_socket.send(data_pack)   # 直接发client_socket.close()

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

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

相关文章

解决docker容器无法关闭的问题

一般正常关闭&#xff1a; docker stop 容器ID解决方法 方法1&#xff1a;强制停止docker kill 容器ID方法2&#xff1a;直接重启dockersudo service docker stop方法3&#xff1a;直接删除容器&#xff0c;重新创建docker rm -f my_container

[python 刷题] 84 Largest Rectangle in Histogram

[python 刷题] 84 Largest Rectangle in Histogram 题目&#xff1a; Given an array of integers heights representing the histogram’s bar height where the width of each bar is 1, return the area of the largest rectangle in the histogram. 这题也是一个典型的 mo…

微调大型语言模型(一):为什么要微调(Why finetune)?

今天我们来学习Deeplearning.ai的在线课程 微调大型语言模型(一)的第一课&#xff1a;为什么要微调(Why finetune)。 我们知道像GPT-3.5这样的大型语言模型(LLM)它所学到的知识截止到2021年9月&#xff0c;那么如果我们向ChatGPT询问2022年以后发生的事情&#xff0c;它可能会…

diff算法面试题

面试题&#xff1a;请阐述vue的diff算法 参考回答&#xff1a; 当组件创建和更新时&#xff0c;vue均会执行内部的update函数&#xff0c;该函数使用render函数生成的虚拟dom树&#xff0c;将新旧两树进行对比&#xff0c;找到差异点&#xff0c;最终更新到真实dom 对比差异的过…

轻松上手Docker:学习如何创建和运行自己的Docker容器

文章目录 轻松上手Docker&#xff1a;学习如何创建和运行自己的Docker容器容器的介绍Docker的技术架构容器的工作机制&#xff08;Docker&#xff09;容器的关键技术 - NamespaceNamespace隔离说明 容器的关键技术 - CgroupDocker环境搭建1&#xff09;安装基础软件包2&#xf…

【0222】存储管理器smgr设计机制,及SMgrRelation、SMgrRelationData的作用(1)

1. 概述 在【0000】PostgreSQL源码剖析教程专栏总目录(2023.09.06更新) 一文的“3.4 VFD机制”章节中,详细讲解了PG内核中VFD(虚拟文件描述符)的实现原理。 本文开始,将来讲解PG内核中另外一个非常重要的知识点,即PG内核的存储管理器 ----- 磁盘介质管理器(SMGR)。 这…

python安全工具开发笔记(四)——python网络编程

一、C/S架构 什么是C/S架构 C : Client S : Server。客户机和服务器结构。 Server 唯一的目的就是等待Client 的请求&#xff0c;Client 连上 Server 发送必要的数据&#xff0c;然后等待Server端完成请求的反馈。 C/S网络编程 Server端进行设置&#xff0c;首先创建一个通信…

【深度学习】实验17 使用GAN生成手写数字样本

文章目录 使用GAN生成手写数字样本附&#xff1a;系列文章 使用GAN生成手写数字样本 生成对抗网络 GAN&#xff08;Generative Adversarial Networks&#xff09;生成对抗网络是一种深度学习模型架构&#xff0c;由深度生成网络&#xff08;Generator&#xff09;和深度鉴别网…

【unity2023打包安卓工程】踩坑记录

这里写自定义目录标题 踩坑记录使用环境Unity的准备工作Windows10 SDKAndroidstudio第一个需要注意的地方第二个需要注意的地方第三个需要注意的地方第四个需要注意的地方第五个需要注意的地方第六个需要注意的 其他unity启动缓慢 更新更新一 2023.9.27 踩坑记录 踩了快一个星期…

codesys【虚轴】

1概述&#xff1a;codesys里有3个轴&#xff1a; 自由编码器&#xff0c;虚轴&#xff0c;实轴。 流程&#xff1a;【高速输入&#xff1a;采集AB脉冲】带》【自由编码器】带》【虚轴】带》【实轴】 1虚轴&#xff1a; 用法和实轴一样。 一般用于&#xff0c;一拖多。 2编…

GEO生信数据挖掘(二)下载基因芯片平台文件及注释

检索到目标数据集后&#xff0c;开始数据挖掘&#xff0c;本文以阿尔兹海默症数据集GSE1297为例 目录 下载平台文件 1.AnnotGPL参数改为TRUE,联网下载芯片平台的soft文件。&#xff08;国内网速奇慢经常中断&#xff09; 2.手工去GEO官网下载 转换芯片探针ID为gene name 拓…

u盘初始化后怎么恢复文件?这几步操作帮你找回

随着科技的进步和便携设备的普及&#xff0c;U盘已经成为我们日常工作和生活中不可缺少的存储介质。然而&#xff0c;在使用U盘的过程中&#xff0c;我们可能会遇到各种问题&#xff0c;其中之一就是意外的初始化导致文件丢失。本文将为大家介绍如何在U盘初始化后恢复文件的方法…

缓存问题解决方案

《服务器开发技术、方法与实用解决方案》 一、缓存预热 在系统刚启动或活动刚开始时&#xff0c;如果缓存中没有数据&#xff0c;那么大量请求将直接访问数据库。如果瞬时访问流量巨大&#xff0c;则可能导致数据库因过载而宕机&#xff0c;甚至引发系统雪崩。因此需要将缓存…

Jenkins学习笔记4

配置构建流程&#xff1a; Jenkins任务创建&#xff1a; 1&#xff09;创建新任务&#xff1a; 把这个Accept first connection改成 No Validation。问题得到解决。 说明下&#xff0c;要确认下主分支的名称是master还是main。 构建触发器这块暂时没有需要配置的。 传输文件…

【yolov1】详解yolov1理论 代码

目标检测要解决的3大问题&#xff1a; 1、有没有&#xff1f; 图片中是否有要检测的物体&#xff1f;&#xff08;检测物体&#xff0c;判定前景背景&#xff09; 2、是什么&#xff1f; 这些物体分别是什么&#xff1f;&#xff08;检测到的物体是什么&#xff09; 3、在…

vuereact质检工具(eslint)安装使用总结

1、ESLint ESLint工具主要类似java中的checkStyle和findbugs&#xff0c;是检查代码样式和逻辑规范的工具。 1.1、ESLint安装流程 打开VSCode软件&#xff0c;打开扩展中心&#xff0c;下载ESLint插件 图1.1 点击后面的install按进行安装&#xff0c;如图1.2所示&#xff1…

spring boot flowable多人前加签

1、前加签插件 package com.xxx.flowable.cmd;import com.xxx.auth.security.user.SecurityUser; import com.xxx.commons.ApplicationContextHolder; import com.google.common.collect.Lists; import org.apache.commons.collections.CollectionUtils; import org.apache.co…

单元测试

一、什么是单元测试 二、Junit单元测试框架 三、如何使用Junit单元测试框架 package study.StringUtils;public class StringUtil {public static void printNumber(String name){if (namenull){System.out.println ("名字的长度是&#xff1a;0");return;}System.ou…

性能测试监控-java分析工具Arthas

Arthas监控docker中的jvm_ray_my的博客-CSDN博客 Quick Start | arthas arthas是什么 Arthas是阿里巴巴开源的Java诊断工具&#xff0c;它可以帮助开发人员快速、方便地定位和解决Java应用的问题。 Arthas主要包括以下功能&#xff1a; 诊断Java应用中的性能问题&#xff…

【面试题精讲】Java移位运算符

“ 有的时候博客内容会有变动&#xff0c;首发博客是最新的&#xff0c;其他博客地址可能会未同步,认准https://blog.zysicyj.top ” 首发博客地址[1] 面试题手册[2] 系列文章地址[3] 1. 什么是移位运算符? 在 Java 中&#xff0c;移位运算符用于对二进制数进行位移操作。它们…