网络编程(三) 文件上传与UDP

一. TCP协议大文件上传

      服务端:

import socket
import struct
import json
import os


server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)


while True:
    conn,addr = server.accept()
    while True:
        try:
            # 先接受报头
            header = conn.recv(4)
            # 解析报头 获取字典长度
            header_len = struct.unpack('i',header)[0]
            # 接收字典
            header_bytes = conn.recv(header_len)
            header_dic = json.loads(header_bytes.decode('utf-8'))
            print(header_dic)
            # 循环接收文件 存储到本地
            file_size = header_dic.get('file_size')
            file_name = header_dic.get('file_name')
            recv_size = 0
            # 文件操作
            with open(file_name,'wb') as f:
                # 循环接收文件数据
                while recv_size < file_size:
                    data = conn.recv(1024)
                    f.write(data)
                    recv_size += len(data)
            print(header_dic.get('msg'))
        except ConnectionResetError:
            break
    conn.close()

        客户端:

 

import socket
import os
import json
import struct


client = socket.socket()
client.connect(('127.0.0.1',8080))

# 文件大小
file_size = os.path.getsize(r'D:\fullstack_s\day32\巴拉巴拉.mp4')
# 文件名字
file_name = '性感荷官在线发牌.mp4'

# 定义一个字典
d = {
    "file_name":file_name,
    "file_size":file_size,
    'msg':'注意身体哦!'
}
data_bytes = json.dumps(d).encode('utf-8')
# 制作字典的报头
header = struct.pack('i',len(data_bytes))
# 发送报头
client.send(header)
# 发送字典
client.send(data_bytes)
# 发送真实数据
with open(r'D:\fullstack_s\day32\巴拉巴拉.mp4','rb') as f:
    for line in f:
        client.send(line)

 

二.  socketserver模块 

    1.能够实现并发效果

    2.udp在使用的时候,多个客户端要有一些io操作, 不然容易卡死

   配合UDP的socketsever模块:

      服务端:

import socketserver


class MyBaby(socketserver.BaseRequestHandler):
    def handle(self):
        # 通信循环
        while True:
            # self.request相当于你的conn通信对象
            data,sock = self.request # 收消息
            print(data)
            sock.sendto(data.upper(),self.client_address)  # self.client_address客户端地址


if __name__ == '__main__':
    server = socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyBaby)
    server.serve_forever()

         客户端:

import socket
import time

client = socket.socket(type=socket.SOCK_DGRAM)
server_addr = ('127.0.0.1',8080)

while True:
    client.sendto(b'hello',server_addr)
    data,addr = client.recvfrom(1024)
    print(data,addr)
    time.sleep(1)

         配合TCP的socketsever模块:

        服务端:

import socketserver


class MyBaby(socketserver.BaseRequestHandler):
    def handle(self):
        # 通信循环
        while True:
            # self.request相当于你的conn通信对象
            data = self.request.recv(1024) # 收消息
            print(data)
            self.request.send(data.upper())


if __name__ == '__main__':
    server = socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyBaby)
    server.serve_forever()

          客户端: 

 

import socket


client = socket.socket()
client.connect(('127.0.0.1',8080))

while True:
    client.send(b'hello')
    data = client.recv(1024)
    print(data)

三. UDP协议: 数据报协议,没有双向通道

       1.UDP协议不存在黏包问题;

       2.客户端可以发空

       3.UDP可实现并发效果(不依赖socketserver模块)

      4.服务端不存在,客户端也可以朝服务端发送数据

import socket


server = socket.socket(type=socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8080))

while True:
    data,addr = server.recvfrom(1024)
    print(data)
    server.sendto(data.upper(),addr)
import socket


client = socket.socket(type=socket.SOCK_DGRAM)
server_addr = ('127.0.0.1',8080)  # 服务端地址,通常写在配置文件中

while True:
    client.sendto(b'hello',server_addr)

    msg,addr = client.recvfrom(1024)
    print(msg)

四.简易版QQ(基于UDP协议)

import socket


server = socket.socket(type=socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8080))

while True:
    msg,addr = server.recvfrom(1024)
    print(msg.decode('utf-8'))
    data = input('>>>:').encode('utf-8')
    server.sendto(data,addr)
import socket


client = socket.socket(type=socket.SOCK_DGRAM)
server_addr = ('127.0.0.1',8080)

while True:
    msg = input('>>>:')
    msg = '客户端1的消息:%s'%msg
    client.sendto(msg.encode('utf-8'),server_addr)
    data,addr = client.recvfrom(1024)
    print(data)
import socket


client = socket.socket(type=socket.SOCK_DGRAM)
server_addr = ('127.0.0.1',8080)

while True:
    msg = input('>>>:')
    msg = '客户端2的消息:%s'%msg
    client.sendto(msg.encode('utf-8'),server_addr)
    data,addr = client.recvfrom(1024)
    print(data)

 

   

 

posted @ 2019-05-19 20:16  纵横捭阖行  阅读(127)  评论(0编辑  收藏  举报