第二十九天

Posted abrahamchen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第二十九天相关的知识,希望对你有一定的参考价值。

基于TCP的大文件发送

#server服务端
import struct
import json
import os
import socket

server = socket.socket()  # 默认TCP协议
server.bind((127.0.0.1,8080))  # 传入IP和端口
server.listen(5)  # 限制半连接池的数量

while True:
    conn,addr = server.accept()  # conn是连接,addr是地址,accept就是阻塞,等待一下,等客户端连接
    while True:
        try:
            header_dict = conn.recv(4) # 接收一个字典的报头
            dict_size = struct.unpack(i,header_dict)[0]  # 解包得到字典的长度
            dict_bytes = conn.recv(dict_size) # 接收一个字典
            dict_json = json.loads(dict_bytes.decode(utf-8))  # 将字典解码并反序列化
            total_size = dict_json.get(file_size) #拿出字典中真实数据的大小
            recv_size = 0
            with open(dict_json.get(file_name),wb) as f:
                while recv_size < total_size:
                    data = conn.recv(1024)  # 接收真实的数据
                    f.write(data)  # 将数据写入文件
                    recv_size += len(data)
                print(上传成功)
        except ConnectionResetError as e:  # 捕获客户端断开产生的错误
            print(e)
            break
    conn.close()  # 关闭客户端套接字

 

 

#client客户端
import socket
import struct
import json
import os

client = socket.socket()
client.connect((127.0.0.1,8080))
while True:
    MOVIE_DIR = rD:\Program Files\feiq\work\untitled\work\sp  # 找到文件路径
    movie_list = os.listdir(MOVIE_DIR) # 将文件夹下的文件名放到列表里
    for i,movie in enumerate(movie_list,1):  # 给列表中的文件名加上序号,从1开始
        print(i,movie)
    choice = input(请输入电影序号>>>:)
    if choice.isdigit():
        choice = int(choice) - 1
        if choice in range(0,len(movie_list)):
            path = movie_list[choice]  # 根据用户的选择,拿到文件名
            file_path = os.path.join(MOVIE_DIR,path)  # 拼接文件名的路径
            file_size = os.path.getsize(file_path)  # 获得该文件的大小
            res_d = 
                file_name:path,
                file_size:file_size,
                msg:注意身体健康
              # 将文件名,大小以及一些其他信息存放在字典里
            json_d = json.dumps(res_d)  # 将字典转换成json格式的数据
            json_bytes = json_d.encode(utf-8)  # 将这个数据变成二进制
            header = struct.pack(i,len(json_bytes))  # 打包一个报头,报头的内容是字典的长度
            client.send(header)  # 发送一个报头
            client.send(json_bytes)  # 发送这个字典
            with open(file_path,rb) as f:  # 找到给文件并准备发送
                for line in f:
                    client.send(line)  # 循环取出数据并发送
        else:
            print(not in range)
    else:
        print(must be a number)

 

 

UDP通信

特点:数据报协议(自带报头),没有双向通道,通信过程类似于发短信。

1.udp协议客户端允许发空

2.udp协议不会粘包

3.udp协议支持并发

***允许发空和不会粘包的原因都是因为基于数据报协议,自带了报头

UDP协议的基本使用:
#服务端
import socket

server = socket.socket(type=socket.SOCK_DGRAM)  # UDP协议
server.bind((127.0.0.1,8080))
#UDP不需要设置半连接池,它也没有半连接池的概念

#因为没有双向通道,不需要accept,直接就到通信循环
while True:
    data,addr = server.recvfrom(1024)
    print(数据:,data)  # 客户端发来的消息
    print(地址:,addr)  # 客户端的地址
    server.sendto(data.upper(),addr)


#客户端
import socket

client = socket.socket(type=socket.SOCK_DGRAM)
# 不需要建立连接,直接进入通信循环
server_address = (127.0.0.1,8080)
while True:
    client.sendto(bhello,server_address)
    data,addr = client.recvfrom(1024)
    print(服务端发来的数据,data)
    print(服务端的地址,addr)

 

简易版本的QQ

#服务端:
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.decode(utf-8))
    msg = input(>>>:)
    server.sendto(msg.encode(utf-8),addr)


#客户端:
import socket

client = socket.socket(type=socket.SOCK_DGRAM)
server_address = (127.0.0.1,8080)

while True:
    msg = input(>>>:)
    res = 来自客户端1的消息:%s%msg
    client.sendto(res.encode(utf-8),server_address)
    data,server_addr = client.recvfrom(1024)
    print(data.decode(utf-8))

 

 

利用socketserver完成并发

#服务器
import socketserver

class MyServer(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            data, sock = self.request
            print(self.client_address)  # 客户端地址
            print(data.decode(utf-8))
            sock.sendto(data.upper(), self.client_address)

if __name__ == __main__:
"""只要有客户端连接,会自动交给自定义类中的handl方法去处理"""    
    server = socketserver.ThreadingUDPServer((127.0.0.1,8080), MyServer)
    server.serve_forever()  # 启动该服务对象

#客户端
import socket
import time

client = socket.socket(type=socket.SOCK_DGRAM)
server_address = (127.0.0.1,8080)

while True:
    client.sendto(bhello,server_address)
    data,addr = client.recvfrom(1024)
    print(data.decode(utf-8),addr)
    time.sleep(1)  # 睡眠1秒,让服务端有反馈的时间

并发:看起来像同时运行的

并行:真正意义上的同时运行

 

以上是关于第二十九天的主要内容,如果未能解决你的问题,请参考以下文章

Mysql基础第二十九天,管理事务处理

第二十九天

Web-第二十九天 Lucene&solr使用二悟空教程

Java自学笔记第二十九天

第二十九天Python学习记录

Java基础第二十九天总结——Java8新特性