IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> python学习-网络UDP 和网络TCP -> 正文阅读

[网络协议]python学习-网络UDP 和网络TCP

1.网络UDP

  1. IP:用来在网络中标记一台电脑,比如192.168.1.1;在本地局域网是唯一的

  2. 端口:在linux系统中,端口可以有65536个(2的16次方)
    知名端口:范围从0-123;80端口给http服务;21端口给FTP服务

  3. socket套接字:是进程间通信的一种方式,它与其他进程间通信的一个主要不同是,它能实现不同主机间的进程间通信,我们平常使用的微信,QQ等都是基于socket来通信的

2.socket套接字使用流程:

①.创建套接字
②.使用套接字收/发数据
③.关闭套接字

创建socket,函数 socket.socket 创建一个 socket,该函数带有两个参数:

import socket
socket.socket(AddressFamily, Type)

Address Family:可以选择使用AF-INET(用于internet进程间通信)或者AF_UNIX(用于同一 机器间进行通信),实际工作中常用的是AF_INET

Type:套接字类型,可以是SOCK_STREAM(流式套接字,主要用于TCP协议) 或者是SOCK_DGRAM(数据套接字,主要用于UDP协议)

创建一个TCP套接字

import socket

# 1.创建套接字
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 2.使用套接字

# 3.关闭套接字
tcp_socket.close()

3.UDP

import socket

# 1.创建udp套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 2.使用套接字

# 3.关闭套接字
udp_socket.close()

1.UDP网络程序,发送,接收数据
①.创建客户端套接字
②.发送/接收数据
③.关闭套接字
在这里插入图片描述
1.使用UDP网络程序-发送,接收数据


from socket import *

# 1.创建套接字
udp_socket = socket(AF_INET, SOCK_DGRAM)

# 2.准备接收方的地址
dest_addr = ('192.168.3.74', 8080)

# 3.从键盘获取数据
send_data = input("请输入要发送的数据:")

# 4. 发送数据到指定的电脑指定的程序中
udp_socket.sendto(send_data.encode('utf-8'), dest_addr)

# 5. 等待接收对方发送的数据
recv_data = udp_socket.recvfrom(1024)

# 6. 显示对方发送的数据
"""
接收到的数据recv_data是一个元组;第一个元素表示对方发送的数据;第二个元素表示对方的ip和端口
"""
print(recv_data[0].decode('utf-8'))
print(recv_data[1])

# 7.关闭套接字
udp_socket.close()

效果如下:
在这里插入图片描述

2.绑定端口:

from socket import *

# 1.创建套接字
udp_socket = socket(AF_INET, SOCK_DGRAM)

# 2.绑定本地的相关信息,如果一个网络程序不绑定,则系统会随机分配
local_addr = ("", 7788)     # ip地址和端口号;ip一般不需要写,表示本机的任何一个ip;端口则指定
udp_socket.bind(local_addr)

# 3. 等待接收对方发送的数据
recv_data = udp_socket.recvfrom(1024)   #1024表示本次接收的最大字节数

# 4.显示接收到的数据
print(recv_data[0].decode('utf-8'))

# 5.关闭套接字
udp_socket.close()

3.UDP聊天器

import socket


def send_msg(udp_socket):
    """获取键盘数据,并将其发送给对方"""
    # 1. 从键盘输入数据
    msg = input("\n请输入要发送的数据:")
    # 2. 输入对方的ip地址
    dest_ip = input("\n请输入对方的ip地址:")
    # 3. 输入对方的port
    dest_port = int(input("\n请输入对方的port:"))
    # 4. 发送数据
    udp_socket.sendto(msg.encode("utf-8"), (dest_ip, dest_port))


def recv_msg(udp_socket):
    """接收数据并显示"""
    # 1.接收数据
    recv_msg = udp_socket.recvfrom(1024)

    # 2.解码
    recv_ip = recv_msg[1]
    recv_msg = recv_msg[0].decode("utf-8")
    # 3.显示接收到的数据
    print(">>>%s:%s" % (str(recv_ip), recv_msg))


def main():
    # 1.创建套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    # 2.绑定本地信息
    udp_socket.bind(("", 7890))

    # 3.选择功能       # 1.发送消息;2.接收消息;其他则输入有误:
    while True:
        op_num = input("请输入要操作的功能序号:")
        # 4.根据选择,调用相应的函数
        if op_num == "1":
            send_msg(udp_socket)
        elif op_num == "2":
            recv_msg(udp_socket)
        else:
            print("输入有误,请重新输入!!")

if __name__ == '__main__':
    main()

4.TCP

1.介绍
TCP协议:传输控制协议;TCP通信需要经过创建连接,数据传送,终止连接三个步骤;类似于日常中的打电话

2.特点
①.面向连接
通信双方必须先建立连接才能进行数据的传输,双方都必须为该连接分配必要的系统内核资源,以管理连接的状态和连接上传输
双方间的数据传输都可以通过这一个连接进行
完成数据交换后,双方必须断开此连接,以释放系统资源
这种连接是一对一的,因此TCP不适用于广播的应用程序
②.可靠传输
1)TCP采购发送应答机制
TCP发送的每个报文都必须得到接收方的应答才认为这个TCP报文传输成功
2)超时重传
3)错误校验
4)流量控制和阻塞管理
用来避免主机发送得过快而使接收方来不及完全收下

3.TCP与UDP的不同点

  • 面向连接(确认有创建三方交握,连接已创建才作传输)
  • 有序数据传输
  • 重发丢失的数据包
  • 舍弃重复的数据包
  • 无差错的数据传输
  • 阻塞/流量控制

4.UDP通信模型
在通信开始之前,不需要建立相关的链接,只需要发送数据即可,类似于生活中,“写信”
在这里插入图片描述

5.TCP通信模型
在通信开始之前,一定要先建立相关的链接,才能发送数据,类似于生活中,“打电话”"
在这里插入图片描述

6.TCP-网络程序-客户端(重点)
1)TCP客户端构建流程
tcp的客户端要比服务器端简单很多,如果说服务器端是需要自己买手机、查手机卡、设置铃声、等待别人打电话流程的话,那么客户端就只需要找一个电话亭,拿起电话拨打即可,流程要少很多

from socket import *

# 1. 创建tcp套接字
tcp_client_socket = socket(AF_INET, SOCK_STREAM)

# 2. 目标地址
server_ip = input("请输入服务器IP:")
server_port = input("请输入服务器PORT:")

# 3. 连接服务器
tcp_client_socket.connect((server_ip, server_port))

# 4. 提示用户输入输入
send_data = input("请输入要发送的数据:")
tcp_client_socket.send(send_data.encode('gbk'))

# 5. 接收对方发送过来的数据,最大接收1024字节
recvData = tcp_client_socket.recv(1024)
print("接收到的数据为:",recvData.decode('gbk'))

# 6. 关闭套接字
tcp_client_socket.close()

7.TCP-服务器(重点)
TCP服务器就好比生活中的电话机;想要别人能够打通咱们的电话获取相应的数据,需要做以下几件事:
买手机;买手机卡;设计手机为正常接听状态;静静的等着别人拨打

想要完成一个tcp服务器的功能,需要的流程如下:
①.socket创建一个套接字
②.bind绑定ip和port
③listen使套接字变为可以被动连接
④.accept等待客户端的数据
⑤.recv/send接收发送数据

from socket import *

tcp_server_socket = socket(AF_INET, SOCK_STREAM)

# 本地信息
address = ("", 7890)

#绑定
tcp_server_socket.bind(address)

# 使用socket创建的套接字默认的属性是主动的,使用listen将其变为被动的
tcp_server_socket.listen()

# 如果有新的客户端来连接服务器,那么就产生一个新的套接字专门为这个客户端服务
# client_socket用来为客户客户端服务
# tcp_server_socket就可以省下来专门等待其他新客户端的连接
client_socket, clientAddr = tcp_server_socket.accept()

#接收对方发送过来的数据
recv_date = client_socket.recv(1024)
print("接收到的数据为:", recv_date.decode('gbk'))

#发送一些数据到客户端
client_socket.send("Thank you!!".encode('gbk'))

client_socket.close()

8.TCP注意点

1.tcp服务器一般情况下都需要绑定,否则客户端找不到这个服务器
2.tcp客户端一般不绑定,因为是主动链接服务器,所以只要确定好服务器的ip、port等信息就好,本地客户端可以随机
3.tcp服务器中通过listen可以将socket创建出来的主动套接字变为被动的,这是做tcp服务器时必须要做的
4.当客户端需要链接服务器时,就需要使用connect进行链接,udp是不需要链接的而是直接发送,但是tcp必须先链接,只有链接成功才能通信
5.当一个tcp客户端连接服务器时,服务器端会有1个新的套接字,这个套接字用来标记这个客户端,单独为这个客户端服务
6.listen后的套接字是被动套接字,用来接收新的客户端的链接请求的,而accept返回的新套接字是标记这个新客户端的
7.关闭listen后的套接字意味着被动套接字关闭了,会导致新的客户端不能够链接服务器,但是之前已经链接成功的客户端正常通信。
8.关闭accept返回的套接字意味着这个客户端已经服务完毕
9.当客户端的套接字调用close后,服务器端会recv解堵塞,并且返回的长度为0,因此服务器可以通过返回数据的长度来区别客户端是否已经下线

9.文件下载器
服务器 参考代码如下:

from socket import *
import sys


def get_file_content(file_name):
    """获取文件的内容"""
    try:
        with open(file_name, "rb") as f:
            content = f.read()
        return content
    except:
        print("没有下载的文件:%s" % file_name)


def main():

    if len(sys.argv) != 2:
        print("请按照如下方式运行:python3 xxx.py 7890")
        return
    else:
        # 运行方式为python3 xxx.py 7890
        port = int(sys.argv[1])


    # 创建socket
    tcp_server_socket = socket(AF_INET, SOCK_STREAM)
    # 本地信息
    address = ('', port)
    # 绑定本地信息
    tcp_server_socket.bind(address)
    # 将主动套接字变为被动套接字
    tcp_server_socket.listen(128)

    while True:
        # 等待客户端的链接,即为这个客户端发送文件
        client_socket, clientAddr = tcp_server_socket.accept()
        # 接收对方发送过来的数据
        recv_data = client_socket.recv(1024)  # 接收1024个字节
        file_name = recv_data.decode("utf-8")
        print("对方请求下载的文件名为:%s" % file_name)
        file_content = get_file_content(file_name)
        # 发送文件的数据给客户端
        # 因为获取打开文件时是以rb方式打开,所以file_content中的数据已经是二进制的格式,因此不需要encode编码
        if file_content:
            client_socket.send(file_content)
        # 关闭这个套接字
        client_socket.close()

    # 关闭监听套接字
    tcp_server_socket.close()


if __name__ == "__main__":
    main()

客户端 参考代码如下:

from socket import *


def main():
    #1. 创建ssocket
    tcp_client_socket = socket(AF_INET, SOCK_STREAM)
    #2. 目的信息
    server_ip = input("请输入服务器ip:")
    server_port = input("请输入服务器port:")
    #3. 链接服务器
    tcp_client_socket.connect((server_ip, server_port))
    #4. 输入要下载的文件名
    file_name = input("请输入要下载的文件名:")
    #5. 发送文件下载请求
    tcp_client_socket.send(file_name.encode('utf-8'))
    #6. 接收对方发送过来的数据,最大接收1024个字节
    recv_data = r=tcp_client_socket.recv(1024)
    # 如果接收到数据再创建文件,否则不创建
    if recv_data:
        with open("[接收]" + file_name, "wb") as f:
            f.write(recv_data)

    #7. 关闭套接字
    tcp_client_socket.close()


if __name__ == '__main__':
    main()

10.TCP的三次握手
在这里插入图片描述

11.TCP的四次挥手
在这里插入图片描述

12.TCP的长连接和短链接
TCP在真正的读写操作之前,server与client之间必须建立一个连接,
当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,
连接的建立通过三次握手,释放则需要四次握手,
所以说每个连接的建立都是需要资源消耗和时间消耗的。
在这里插入图片描述

12.1 TCP短连接
模拟一种TCP短连接的情况:

client 向 server 发起连接请求
server 接到请求,双方建立连接
client 向 server 发送消息
server 回应 client
一次读写完成,此时双方任何一个都可以发起 close 操作
在步骤5中,一般都是 client 先发起 close 操作。当然也不排除有特殊的情况。

从上面的描述看,短连接一般只会在 client/server 间传递一次读写操作!

12.2 TCP长连接
再模拟一种长连接的情况:

client 向 server 发起连接
server 接到请求,双方建立连接
client 向 server 发送消息
server 回应 client
一次读写完成,连接不关闭
后续读写操作…
长时间操作之后client发起关闭请求

12.3 操作过程
短连接的操作步骤是:
建立连接——数据传输——关闭连接…建立连接——数据传输——关闭连接

长连接的操作步骤是:
建立连接——数据传输…(保持连接)…数据传输——关闭连接

TCP长/短连接的优点和缺点
①.长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。

②.client与server之间的连接如果一直不关闭的话,会存在一个问题,
随着客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略,
如关闭一些长时间没有读写事件发生的连接,这样可以避免一些恶意连接导致server端服务受损;
如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,
这样可以完全避免某个蛋疼的客户端连累后端服务。

③.短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。
但如果客户请求频繁,将在TCP的建立和关闭操作上浪费时间和带宽。

TCP长/短连接的应用场景
①.长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。
每个TCP连接都需要三次握手,这需要时间,如果每个操作都是先连接,
再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,
再次处理时直接发送数据包就OK了,不用建立TCP连接。
例如:数据库的连接用长连接,如果用短连接频繁的通信会造成socket错误,
而且频繁的socket 创建也是对资源的浪费。

②.而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,
而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,
如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,
那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-09-04 01:45:01  更:2022-09-04 01:45:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:56:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码