TCP编程实例

TCP实例

文件的上传,下载,查看
服务端代码
from socket import *
import os
import pickle

# 查看文件目录
def show_list(new_socket):
    data = os.listdir()
    data = pickle.dumps(data)
    new_socket.send(data)
    new_socket.close()

# 下载文件
def download(new_socket, data):
    data = data.decode("utf-8")
    print("下载")
    if str(data[2:]) in os.listdir():
        fr = open(data[2:], "rb")
        content = fr.read(1024)
        while content:
            new_socket.send(content)
            content = fr.read(1024)
        new_socket.close()
    else:
        new_socket.send("".encode('utf-8'))
        print('没有该文件')
        new_socket.close()

# 上传文件
def upload(new_socket, data):
    file_name = data[2:].decode("utf-8")
    fw = open(file_name, "wb")
    content = new_socket.recv(1024)
    con = content.split("@".encode('utf-8'))[1]
    while con:
        fw.write(con)
        con = new_socket.recv(1024)
    print("上传成功")
    new_socket.close()


def main():
    # 创建一个对象
    tcp_server = socket(AF_INET, SOCK_STREAM)
    tcp_server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    # 绑定端口ip
    tcp_server.bind(("", 2121))
    # 监听
    tcp_server.listen(5)
    while True:
        # 等待连接
        new_socket, client_info = tcp_server.accept()
        # 接收消息
        data = new_socket.recv(1024)
        # 查看获取的第一位是什么
        if data[0:1] == b"L":
            show_list(new_socket)
        elif data[0:1] == b"G":
            download(new_socket, data)
        elif data[0:1] == b"U":
            upload(new_socket, data)


if __name__ == '__main__':
    main()

客户端
from socket import *
import pickle

# 查看文件列表
def show_list():
    print("查看目录")
    # 创建对象
    tcp_client = socket(AF_INET, SOCK_STREAM)
    # 创建连接
    tcp_client.connect(("47.96.154.250", 2121))
    # 发送消息
    tcp_client.send("L".encode('utf-8'))
    # 接收消息
    data = tcp_client.recv(1024)
    data = pickle.loads(data)
    print(f"{data}")
    tcp_client.close()

# 下载文件
def download(send_data):
    # print("下载文件")
    # 创建对象
    tcp_client = socket(AF_INET, SOCK_STREAM)
    # 创建连接
    tcp_client.connect(("47.96.154.250", 2121))
    # 发送消息
    tcp_client.send(send_data.encode('utf-8'))
    # 接收消息
    data = tcp_client.recv(1024)
    if data:
        fw = open(send_data[2:], "wb")
        while data:
            fw.write(bytes(data))
            data = tcp_client.recv(1024)
        print("下载完毕")
        tcp_client.close()
    else:
        print("该文件不存在,请检查文件名是否正确")

# 上传文件
def upload(send_data):
    # print("上传文件")
    # 创建对象
    tcp_client = socket(AF_INET, SOCK_STREAM)
    # 创建连接
    tcp_client.connect(("47.96.154.250", 2121))
    # 发送消息
    tcp_client.send(send_data.encode('utf-8'))
    # 获取文件名
    file_name = send_data[2:]
    # 使用@ 将文件名和文件内容分隔
    tcp_client.send((file_name + "@").encode('utf-8'))
    fr = open(file_name, "rb")
    content = fr.read(1024)
    while content:
        tcp_client.send(content)
        content = fr.read(1024)
    print("上传完毕")
    tcp_client.close()


def main():
    send_data = input("请输入:")
    while True:
        if send_data[0].upper() == 'L':
            show_list()
        elif send_data[0].upper() == 'G':
            download(send_data)
        elif send_data[0].upper() == 'U':
            upload(send_data)
        send_data = input("请输入:")


if __name__ == '__main__':
    main()

序列化和反序列化
import pickle

# 将指定的Python对象通过pickle序列化作为bytes对象返回,而不是将其写入文件
dumps(obj)

# 将通过pickle序列化后得到的字节对象进行反序列化,转换为Python对象并返回
loads(bytes_object)

# 将指定的Python对象通过pickle序列化后写入打开的文件对象中,等价于`Pickler(file, protocol).dump(obj)`
dump(obj)

# 从打开的文件对象中读取pickled对象表现形式并返回通过pickle反序列化后得到的Python对象
load(file)

TCP三次握手和四次分手

TCP为什么要三次握手
  1. 第一次握手 客户端向服务端发送一个请求包 当服务端收到这个请求包的时间可以确定服务端的收信功能 和客户端的发信功能
  2. 第二次握手 服务端向客户端发送一个确认包,并同时发送一个请求包, 客户端可以确认 自己可以收发信,服务端也可以收发信
  3. 第三次握手 客户端向服务端发送一个确认包 服务端可以确认 自己的发信功能和客户端的收信功能,结合第一次握手的信息已经确认双方收发信功能没有问题
那分手为什么需要四次
  1. 客户端发送一个分手包
  2. 服务端收到后立马确认
  3. 把手头剩余的事情做完后再次发送分手包给客户端
  4. 客户端收到后再次发送确认包等待2MSL时间后退出,服务端收到确认包后结束连接,如果在没有收到会再次发送分手包

什么是2MSL

MSL是客户端到服务端一次通信的最长时间,如果在这个时间内没有送达,认为丢包了

一来一回最长时间就是2MSL,所以任何一方在发出信息后,如果2MSL内没有收到回复,就认为丢包

通常在四次握手最后一次,客户端发出最后确认分手包后,服务端在收到这个包后会断开连接,无法再发送消息

所以客户端只有等待这么长时间,如果在这个时间段内没有再次收到新的分手包,就认为服务端已经下线,我也是可以离开

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值