python高级之网络概述2

python高级之网络概述2

2.11综合案例:udp聊天器

import socket

def send_data1(udp_socket):
    # 准备发送数据
    send_data = input("请输入您要发送的数据:")
    # 对发送的数据进行二进制编码
    send_content = send_data.encode("utf-8")
    ip_address = input("请输入对方的ip地址:")
    port = int(input("请输入对方的端口号:"))
    # 发送数据
    udp_socket.sendto(send_content, (ip_address, port))

def receive_data1(udp_socket):
    # 接收数据
    recv_data, ip_port = udp_socket.recvfrom(1024)
    # 对接收的数据进行解码
    recv_content = recv_data.decode("utf-8")
    print(recv_content, ip_port)

if __name__ == '__main__':
        # 创建套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    udp_socket.bind(("", 8080))
    while True:
        num = int(input("请输入功能对应的数字:1.发送数据 2.接收数据 3.退出"))
        if num == 1:
            send_data1(udp_socket)
        elif num == 2:
            receive_data1(udp_socket)
        elif num == 3:
            break
    # 关闭套接字
    udp_socket.close()

2.12tcp网络程序——tcp客户端

import socket

if __name__ == '__main__':
    # 创建tcp客户端socket
    # 1. AF_INET:表示ipv4的地址类型
    # 2. SOCK_STREAM: 表示使用tcp的传输协议
    tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 和服务端socket建立连接
    tcp_client_socket.connect(("192.168.131.106", 8989))
    # 准备发送的数据
    send_content = "哈哈,我使用tcp发送数据啦~"
    # 对数据进行gbk的编码
    send_data = send_content.encode("gbk")
    # 发送数据
    tcp_client_socket.send(send_data)
    # 接收数据, 1024:表示每次接收最大的字节数
    recv_data = tcp_client_socket.recv(1024)
    # 解码数据
    recv_content = recv_data.decode("gbk")
    print(recv_content)
    # 关闭socket
    tcp_client_socket.close()

2.13tcp网络程序——tcp服务端

import socket

if __name__ == '__main__':

# 创建tcp服务端socket

​    tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

# 扩展-立即释放端口号,重用端口

# SOL_SOCKET: 表示当前socket

# SO_REUSEADDR: 是否立即是否端口选项

# True:表示立即是否端口

​    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

# 绑定端口号

​    tcp_server_socket.bind(("", 7878))

# 设置监听,把主动套接字变成被动套接字, 被动套接字:以后只能接收客户端连接请求,不能收发消息,收发消息使用返回的新套接字

# 128:表示等待的最大连接数

​    tcp_server_socket.listen(128)

# 等待接收客户端连接请求, 返回一个新的套接字说明建立连接成功,以后和客户端通信使用service_client_socket

# accept会一直等待客户端建立连接,只有连接建立成功才会继续往下执行代码否则一直等待

​    service_client_socket, ip_port = tcp_server_socket.accept()print(ip_port)

# 接收客户端的消息

​    recv_data = service_client_socket.recv(1024)print(recv_data, len(recv_data))

# 解码数据

​    recv_content = recv_data.decode("gbk")print(recv_content)

# 发送数据

service_client_socket.send("ok,问题正在处理中...".encode("gbk"))

# 关闭服务于客户端的socket

service_client_socket.close()

# 关闭服务端的socket

tcp_server_socket.close()

2.14案例:文件下载器

2.14.1tcp文件下载器客户端
import socket

if __name__ == '__main__':

# 创建tcp客户端socket

​    tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 和服务端socket建立连接

​    tcp_client_socket.connect(("192.168.131.106", 7878))

# 接收用户输入的文件名

​    file_name = input("请输入您要下载的文件对应的名字:")

# 对字符串进行编码

​    file_name_data = file_name.encode("gbk")

# 发送下载文件的请求信息

​    tcp_client_socket.send(file_name_data)

# 定义二进制空的数据

​    result_file_data = b""

# 循环接收数据while True:

# 获取服务端发送的文件二进制数据

​        file_data = tcp_client_socket.recv(1024)if file_data:

# 拼接每次读取的数据

​            result_file_data += file_data
​        else:break

# 判断文件是否有数据if result_file_data:

# 写入到指定文件里面, with open 文件操作完成以后关闭文件是系统自己操作的with open("/home/python/Desktop/" + file_name, "wb") as file:file.write(result_file_data)else:print("文件不存在")

# 关闭socket

​    tcp_client_socket.close()
2.14.2tcp文件下载器服务端
import socket
import os

if __name__ == '__main__':

# 创建tcp服务端socket

​    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定端口号

​    tcp_server_socket.bind(("", 7878))

# 设置监听,把主动套接字改成被动套接字,被动套接字只能接收客户端连接请求,不能收发消息,收发消息使用新的套接字

​    tcp_server_socket.listen(128)

# 注意点:目前服务端是单任务的一个人下载完成以后另外一个人才能再下载

# 循环接收客户端连接请求while True:

# 等待接收客户端的连接请求

​        tcp_service_socket, ip_port = tcp_server_socket.accept()print(ip_port)

# 接收客户端的请求信息,其实文件名

​        file_name_data = tcp_service_socket.recv(1024)

# 对二进制数据进行解码获取文件名字符串

​        file_name = file_name_data.decode("gbk")

# "桌面路径/" + file_name 判断指定路径是否有对应的文件

# file_name在当前工程判断该文件是否存在if os.path.exists(file_name):

# 打开指定文件把数据发送给客户端with open(file_name, "rb") as file:while True:

# 读取文件中的数据

​                    file_data = file.read(1024)

# 判断数据是否为空if file_data:

# 发送数据给客户端

​                        tcp_service_socket.send(file_data)else:breakprint(file_name, ip_port)

# 和客户端终止服务

​        tcp_service_socket.close()

# 关闭服务端套接字,以后不再接收客户端的连接请求

​    tcp_server_socket.close()

2.15tcp的三次握手和四次挥手

2.15.1tcp的三次握手

标志位:

SYN:表示连接请求

ACK:表示确认

FIN:表示关闭连接

序号:

seq:表示报文序号

ack:表示确认序号

![img](file:///C:/%E8%BF%85%E9%9B%B7%E4%B8%8B%E8%BD%BD/Learn/python%E9%AB%98%E7%BA%A7%E4%B8%8A%E8%AF%BE%E8%AF%BE%E4%BB%B6/day04/imgs/tcp%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B.png)

图解流程如下:

  1. 第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
  2. 第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack (number )=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
  3. 第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
2.15.2tcp的四次挥手

![img](file:///C:/%E8%BF%85%E9%9B%B7%E4%B8%8B%E8%BD%BD/Learn/python%E9%AB%98%E7%BA%A7%E4%B8%8A%E8%AF%BE%E8%AF%BE%E4%BB%B6/day04/imgs/tcp%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B.png)

图解流程如下:

  1. 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送。
  2. 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1。
  3. 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送。
  4. 第四次挥手:Client收到FIN后,接着发送一个ACK给Server,确认序号为收到序号+1。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值