基于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 = r'D:\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(b'hello',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(b'hello',server_address)
data,addr = client.recvfrom(1024)
print(data.decode('utf-8'),addr)
time.sleep(1) # 睡眠1秒,让服务端有反馈的时间

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

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

基于TCP的大文件发送、UDP、socketserver的更多相关文章

  1. Linux Linux程序练习十一(网络编程大文件发送UDP版)

    //网络编程发送端--大文件传输(UDP) #include <stdio.h> #include <stdlib.h> #include <string.h> # ...

  2. (网络编程)基于tcp(粘包问题) udp协议的套接字通信

    import   socket 1.通信套接字(1人1句)服务端和1个客户端 2.通信循环(1人多句)服务端和1个客户端 3.通信循环(多人(串行)多句)多个客户端(服务端服务死:1个客户端---&g ...

  3. TCP大文件发送案例以及UDP介绍

    基于TCP的大文件发送 #server服务端 import struct import json import os import socket server = socket.socket() # ...

  4. 基于TCP协议的大文件传输(粘包问题处理)

    基于TCP的大文件上传服务端实现 # 服务端 # -*- coding: utf-8 -*- from socket import * import json, struct server = soc ...

  5. 网络编程----socket介绍、基于tcp协议的套接字实现、基于udp协议的套接字实现

    一.客户端/服务器架构(C/S架构)                                                即C/S架构,包括: 1.硬件C/S架构(打印机) 2.软件C/S架 ...

  6. 基于TCP和UDP的socket

    为什么学习socket 你自己现在完全可以写一些小程序了,但是前面的学习和练习,我们写的代码都是在自己的电脑上运行的,虽然我们学过了模块引入,文件引入import等等,我可以在程序中获取到另一个文件的 ...

  7. 基于tcp/udp的协议

    使用TCP协议的常见端口主要有以下几种: (1) FTP:定义了文件传输协议,使用21端口.常说某某计算机开了FTP服务便是启动了文件传输服务.下载文件,上传主页,都要用到FTP服务. (2) Tel ...

  8. Day9 基于TCP的套接字和基于UDP的套接字

    服务端: ss=socket() #创建服务器套接字 ss.bind() #把地址绑定到套接字 ss.listen() #监听套接字, inf_loop: #服务器无限循环 cs=ss.accept( ...

  9. Nginx基于TCP/UDP端口的四层负载均衡(stream模块)配置梳理

    通过我们会用Nginx的upstream做基于http/https端口的7层负载均衡,由于Nginx老版本不支持tcp协议,所以基于tcp/udp端口的四层负载均衡一般用LVS或Haproxy来做.至 ...

随机推荐

  1. Eclipse中常用的快捷键总结!不收藏后悔!

    Eclipse中常用的快捷键总结!不收藏后悔!Ctrl+1 快速修复(最经典的快捷键,就不用多说了)Ctrl+D: 删除当前行Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ ...

  2. 线段树--线段树【模板1】P3372

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入格式 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含 ...

  3. 微信小程序下载图片到本地

    downloadImg: function(e){ //触发函数 console.log(e.currentTarget.dataset.url) wx.downloadFile({ url: e.c ...

  4. [极客大挑战 2019]Http

    0x00知识点 了解HTTP协议,使用bp伪造. 0x01 解题 首先查看源代码,找到Secret.php 访问 使用bp查看 提示我们需要来自该网址,直接改header头信息即可,我们可以通过使用r ...

  5. 计蒜客 方程的解数(DFS)

    问题描述 输出格式 输出一行,输出一个整数,表示方程的整数解的个数. 样例输入 - 样例输出 #include <stdio.h> #include <string.h> #i ...

  6. iTOP-4418开发板TF卡烧写-引导uboot

    基于迅为iTOP-4418开发板 将 TF 卡接入开发板,将拨码开关设置为 TF 卡启动,进入 uboot 模式,如下图所示. 如下图所示,使用命令“fastboot”,接着就可以通过 OTG 给 e ...

  7. 17.3.12---socket

    1----如果要用python做一个服务器和客户端的通信程序,那么就一定得选择标准库中的scoket套接字模块,它支持多种网络协议:TCP/IP    ,ICMP/IP,            UDP ...

  8. 第二季第八天 HTML5新特性

    在函数内部window.a =  a  在全局中就可以拿到这个变量 变量命名.作为函数的参数的时候要详细.调用的时候可以简单点 做全局变量的两个方案 1.绑在标签上data 2.闭包 视频一般都是二进 ...

  9. \_\_del\_\_

    __del__ 一.__del__ __del__也称之为析构方法 __del__会在对象被删除之前自动触发 print('主')class People: def __init__(self, na ...

  10. 关于mysql一边查一边更新

    update test_table set user_id = 112 where id in (select id from ( select id from test_table where nu ...