文件上传下载-UDP协议-socketserver并发

recv原理

1.验证服务端缓冲区数据没有取完,又执行了recv执行,recv会继续取值。

复制代码
# 服务器:
import socket

phone =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
conn, client_addr = phone.accept()
from_client_data1 = conn.recv(2)
print(from_client_data1)
from_client_data2 = conn.recv(2)
print(from_client_data2)
from_client_data3 = conn.recv(1)
print(from_client_data3)
conn.close()
phone.close()

# 客户端:
import socket
import time
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
phone.send('hello'.encode('utf-8'))
time.sleep(20)
phone.close()
复制代码

 2.验证服务端缓冲区取完了,又执行了recv执行,此时客户端20秒内不关闭的前提下,recv处于阻塞状态

复制代码
# 服务端:
import socket

phone =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
conn, client_addr = phone.accept()
from_client_data = conn.recv(1024)
print(from_client_data)
print(111)
conn.recv(1024) # 此时程序阻塞20秒左右,因为缓冲区的数据取完了,并且20秒内,客户端没有关闭。
print(222)

conn.close()
phone.close()


# 客户端:
import socket
import time
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
phone.send('hello'.encode('utf-8'))
time.sleep(20)
phone.close()
复制代码

3. 服务端缓冲区的数据取完之后,又执行了recv执行,此时客户端处于关闭状态,则recv会取到空字符串。

复制代码
# 服务端:
import socket

phone =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
conn, client_addr = phone.accept()
from_client_data1 = conn.recv(1024)
print(from_client_data1)
from_client_data2 = conn.recv(1024)
print(from_client_data2)
from_client_data3 = conn.recv(1024)
print(from_client_data3)
conn.close()
phone.close()


# 客户端:
import socket
import time
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
phone.send('hello'.encode('utf-8'))
phone.close()
复制代码

 用户登录功能实现:

复制代码
用户登录作业用tcp协议下的socket完成:
1,服务端:
    等待客户端来发送数据:用户名,密码。
    本地文件汇总查看用户名密码是否合法。
    合法:登录成功。
    否则:用户名或者密码错误。
2,客户端:
    用户输入: 用户名,密码。
    发送到服务端进行校验。

服务端:
import socket

server = socket.socket()
server.bind(('127.0.0.1',9045))
server.listen(5)
try:
    while 1:
        conn,addr = server.accept()
        flag = 0
        while not flag:
            user_pwd = conn.recv(1024).decode('utf-8')
            with open ('userinfo',encoding='utf-8')as f:
                for i in f:
                    if i.strip() == user_pwd:
                        conn.send('success'.encode('utf-8'))
                        flag =1
                        break
                else:
                    conn.send('failed'.encode('utf-8'))
        conn.close()
finally:
    server.close()

    
    
客户端:
import socket

client = socket.socket()
client.connect(('127.0.0.1',9045))
while 1:
    user = input('用户名>>>').strip()
    pwd = input('密码>>>').strip()
    user_pwd = user + '|' + pwd
    client.send(user_pwd.encode('utf-8'))
    result = client.recv(1024)
    if result == b'success':
        print('登录成功')
        break
    else:
        print('用户名或密码错误')
client.close()
复制代码

 上传功能实现:

复制代码
服务端:
import socket
import json
import struct
import os

server = socket.socket()
server.bind(('127.0.0.1',9345))
server.listen()

file_base_path = 'D:上传下载'
conn,addr = server.accept()

head_dic_json_bytes_struct = conn.recv(4)    #接收4个字节
head_dic_json_bytes_len = struct.unpack('i',head_dic_json_bytes_struct)[0]   # 转换成int长度
head_dic_json_bytes = conn.recv(head_dic_json_bytes_len)    # 接收报头字典的字节
head_dic_json = head_dic_json_bytes.decode('utf-8')        # 转换成json字符串
head_dic = json.loads(head_dic_json)                        # 转换成报头字典

file_path = os.path.join(file_base_path,head_dic['file_name'])
with open(file_path,mode='wb')as f:
    total_data_size = 0
    while total_data_size < head_dic['file_size']:
        every_data = conn.recv(1024)
        f.write(every_data)
        total_data_size += len(every_data)

conn.close()
server.close()

客户端:
import socket
import json
import struct
import os

client = socket.socket()
client.connect(('127.0.0.1',9345))
#1.自定制报头
head_dic = {
    'file_name':'今日总结.mp4',
    'file_path':r'F:workspace_pythons19day30文件上传今日总结.mp4',
    'file_size':None
}
head_dic['file_size'] = os.path.getsize(head_dic['file_path'])
head_dic_json =json.dumps(head_dic)       #转换成json字符串
head_dic_json_bytes = head_dic_json.encode('utf-8')   #将字符串转换成字节
head_dic_json_bytes_struct = struct.pack('i',len(head_dic_json_bytes))   #转换成4个字节
client.send(head_dic_json_bytes_struct)
client.send(head_dic_json_bytes)
with open(head_dic['file_name'],mode='rb')as f1:
    total_data_size = 0
    while total_data_size < head_dic['file_size']:
        every_data = f1.read(1024)
        client.send(every_data)
        total_data_size += len(every_data)
client.close()
复制代码

基于UDP协议的socket

TCP协议有回执,丢包跟网络相关(网络断开或者遭遇抓包)

UDP协议无阻塞,没有粘包现象

复制代码
服务端:
import socket
server = socket.socket(type=socket.SOCK_DGRAM)  # udp协议
server.bind(('127.0.0.1',8848))
try:
    while 1:
        client_data, client_address = server.recvfrom(1024)
        print('来自%s消息: %s'%(client_address,client_data.decode('utf-8')))
        to_client_data = input('回复:').strip().encode('utf-8')
        server.sendto(to_client_data,client_address)
finally:
    server.close()
    
客户端:
import socket
client = socket.socket(type=socket.SOCK_DGRAM)  # udp协议
while 1:
    to_server_data = input('给服务端发送:').strip().encode('utf-8')
    client.sendto(to_server_data,('127.0.0.1',8848))
    server_data, server_address = client.recvfrom(1024)
    print('33[1;35;0m来自%s的信息: %s33[0m' %(server_address,server_data.decode('utf-8')))
复制代码

socketserver

复制代码
服务端:
import socketserver

class MyServer(socketserver.BaseRequestHandler):   # MyServer类名不固定,但是必须要继承socketserver.BaseRequestHandler

    def handle(self):  # handle方法名固定写法
        # self.request conn
        while 1:
            from_client_data = self.request.recv(1024)
            print(from_client_data.decode('utf-8'))
            to_client_data = input('>>>').strip().encode('utf-8')
            self.request.send(to_client_data)


if __name__ == '__main__':
    ip_port = ('127.0.0.1', 8888)
    socketserver.TCPServer.allow_reuse_address = True
    server = socketserver.ThreadingTCPServer(ip_port,MyServer)  # 固定写法((ip地址,端口),MyServer)
    # 源码显示:上一行代码: 创建socket对象,绑定ip地址和端口,监听
    server.serve_forever()

    
客户端:
import socket
client = socket.socket()
client.connect(('127.0.0.1',8888))

while 1:
    to_server_data = input('>>>').strip().encode('utf-8')
    client.send(to_server_data)
    from_server_data = client.recv(1024).decode('utf-8')
    print(from_server_data)
原文地址:https://www.cnblogs.com/sandy-123/p/10429335.html