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

这篇具有很好参考价值的文章主要介绍了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)

    # 指定要连接的IP
    host_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'))
        break

print('客户端关闭')

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(最长报文段寿命)后结束文章来源地址https://www.toymoban.com/news/detail-730653.html

四 使用TCP传输较大的文件

4.1 服务端代码

from socket import *
import struct
server_socket = socket(AF_INET, SOCK_STREAM)  # TCP

host_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 struct

client_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:
        break
    client_socket.send(data_pack)   # 直接发

client_socket.close()

到了这里,关于Python 笔记02 (网络交互 TCP/UDP)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 计算机网络笔记:TCP协议 和UDP协议(传输层)

    TCP 和 UDP都是传输层协议,他们都属于TCP/IP协议族。 TCP的全称是 传输控制协议 是一种 面向连接的、可靠的、基于字节流 的 传输层 通信协议。TCP 是面向连接的、可靠的流协议(流就是指不间断的数据结构) TCP报文 是TCP层传输的数据单元,也称为 报文段 ,一个TCP报文段由

    2024年02月02日
    浏览(39)
  • 《TCP/IP网络编程》阅读笔记--基于UDP的服务器端/客户端

    目录 1--TCP和UDP的主要区别 2--基于 UDP 的数据 I/O 函数 3--基于 UDP 的回声服务器端/客户端 4--UDP客户端Socket的地址分配 5--UDP存在数据边界 6--UDP已连接与未连接的设置 ① TCP 提供的是可靠数据传输服务,而 UDP 提供的是不可靠数据传输服务; ② UDP 在结构上比 TCP 更简洁,其不会

    2024年02月09日
    浏览(50)
  • python编写TCP和UDP测试工具

    通过python编写的TCPUDP协议的客户端和服务端,支持IPV4和IPV6的网络环境,同时新增加客户端ip和端口绑定功能。 client客户端 server服务端 python3.x和python2.x代码逻辑一致,只是部分函数写法不一样,只需要修改写法后同样可以在python2.x环境使用 1、python3.x的print()函数有括号,py

    2024年02月03日
    浏览(35)
  • python模拟TCP与UDP发送数据包

    在项目测试中需要发送指定内容的数据包到目标位置,并且需要发送的数量极大,真实环境无法满足测试需求,但是以Python为基础语言,结合Socket和Scrapy便可以支撑测试,其中Socket可以支持大量数据包由本机发送给目标机,scapy则可以模拟发生源IP发送数据包给目标及,但每秒

    2024年02月05日
    浏览(33)
  • 基于python socket实现TCP/UDP通信

    两个应用程序如果需要进行通讯最基本的一个前提就是能够唯一的标示一个进程,我们知道IP层的ip地址可以唯一标示主机,而TCP层协议和端口号可以唯一标示主机的一个进程,这样我们可以利用ip地址+协议+端口号唯一标示网络中的一个进程。能够唯一标示网络中的进程后

    2024年02月16日
    浏览(38)
  • Python使用 Twisted 实现 TCP/UDP Socket 编程

    更多文章: 技数未来 环境准备: - 安装Python:确保你已经安装了Python解释器。 - 安装Twisted:可以通过pip命令来安装Twisted库,运行`pip install twisted`即可。 依赖的类库: - twisted.internet.protocol:包含了实现TCP/UDP Socket编程所需的协议类。 - twisted.internet.reactor:用于处理事件循环

    2024年02月16日
    浏览(34)
  • 【Python爬虫与数据分析】UDP/TCP通信协议

    目录 一、网络编程基础 二、UDP协议 三、TCP协议 数据编码与解码 str - bytes :encode编码,发送信息的时候用encode编码 bytes - str :decode解码,打印接收的信息用decode解码 socket socket套接字,是进程间通信的工具,也能不同主机间的网络通信 首先通过ip地址找到网络中对应的主机

    2024年02月12日
    浏览(34)
  • socket概述 python中如何使用TCP/UDP协议实现通信-教程

    很多编程语言中,都 使用scoket套接字实现网络通信。 Socket是对TCP/IP协议的封装,Socket本身就是一个调用接口(API),方便程序员用Socket使用TCP/IP协议簇,实现网络通信。 不同编程语言,shiyongSocket通信的语法有所区别,但基本原理类型相似。 它的两种方式,分别是TCP和UDP协

    2024年02月13日
    浏览(32)
  • Python进阶篇(三)-- TCP套接字与UDP套接字编程

    1.1 介绍         本文将首先利用 Python 实现面向TCP连接的套接字编程基础知识:如何创建套接字,将其绑定到特定的地址和端口,以及发送和接收数据包。其次还将学习 HTTP 协议格式的相关知识。在此基础上,本篇将用 Python 语言开发一个简单的 Web 服务器,它仅能处理一

    2023年04月23日
    浏览(34)
  • python3套接字编程之socket和socketserver(TCP和UDP通信)

    socket和socketserver是python3中socket通信模块,关于其使用做如下总结。 目录 1.socket 1.1模块引入 1.2套接字获取 1.3套接字接口 1.3.1 服务端 1.3.2 客户端套接字函数 1.3.3 公共套接字函数 1.3.4 面向锁的套接字方法 1.3.5 面向文件的套接字的函数 2.socketserver 3.TCP 3.1 socket类型TCP 3.2 sockets

    2024年02月15日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包