基于tcp的下载文件,以及struct模块的应用。
一 基于TCP的下载
客户端:
from socket import *
import os
def main():
tcp_socket = socket(AF_INET, SOCK_STREAM)# 建立套接字
tcp_ip = input("请输入ip:")
tcp_port = int(input("请输入端口:"))# 接收用输入的服务器端的ip和端口
tcp_socket.connect((tcp_ip, tcp_port))# 连接服务器
file_name = input("请输入要下载的文件名:")# 输入要下载的文件名
tcp_socket.send(file_name.encode())# 将文件名发送至服务器端
new_file = open(file_name, "wb")# 创建一个空文件
time = 0# 用于计算读取的字节数
while True:
mes = tcp_socket.recv(1024)# 接收服务器端返回的内容
if mes:# 如果内容不为空执行
new_file.write(mes.decode())# 解码并向文件内写入
time += len(mes)# 计算字节
else:
if time == 0:# 如果字节数为空即未收到内容
new_file.close()# 关闭文件
os.remove(file_name) # 删除刚刚创建的文件
print("没有您要下载的文件")
else:
print("文件下载成功") # 如过time有值时name文件传输完成
break
tcp_socket.close() # 关闭套接字
if __name__ == '__main__':
main()
服务端:
import socket
def file_deal(file_name):# 定义函数用于处理用户索要下载的文件
try:
files = open(file_name, "rb") # 二进制方式读取
mes = files.read()
except:
print("没有该文件")
else:
files.close()
return mes
def main():
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 创建套接字
tcp_socket.bind(("",8080)) # 固定端口号
tcp_socket.listen(128)# 将主动套接字转为被动套接字,监听连接客户端
while True:
client_socket,client_addr = tcp_socket.accept()# 利用accept获取分套接字以及客户端的地址
file_name = client_socket.recv(4096)# 接收客户端的数据
mes = file_deal(file_name)# 调用函数处理用户下载的文件
if mes:# 如果文件不为空发送
client_socket.send(mes)
client_socket.close()#关闭分套接字
if __name__ == "__main__":
main()
二 基于TCP的套接字通讯:
客户端client_side: import socket
c=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #套接字
c.connect(('127.0.0.1',)) #connect对应server_side中的accept。
while True:
try:
msg=input('>:')
c.send(msg.encode())
s_data=c.recv()
print(s_data.decode())
except Exception as e:
print(e)
c.close() 服务端server_side:
import socket s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('127.0.0.1',8080))
s.listen(5) while True:
conn,addr=s.accept()#等待客户端的连接,对应client_side端的connect。
try:
while True:
client_data=conn.recv(1024)
conn.send(client_data.upper())
print(client_data.decode())
except Exception as e:
print(e)
conn.close() s.close()
TCP的一个通讯过程,服务端先启动,通过导入socket模块,产生一个客户端套接字,首先我们应该绑定一个固定的ip与端口port,那么客户端再访问就不需要每次都去找
服务端。那么套接字下面的listen()功能,主要是限制同时请求数,也就是listen控制的是同时请求数,而不是连接数,连接数是跟服务器的性能相关的,
同时请求数,而不是连接数,连接数是跟服务器的性能相关的,性能越好能建的连接数也越多,这些都准备好之后就是等待客户端的连接请求,我们这里然后再accept()
这里等待客户端连接进来,那么accept()其实就对应于客户端的connect(),那么一旦连接建成,就准备进行数据的传输,我们客户端首先发一个数据请求,其实客户端的
数据首先是send()到客户端的一个操作系统的缓存中,因为应用软件是没办法直接操作网卡进行数据的传输,所以他要借助操作系统来调用网卡,进行数据的传输,
那么再send()数据的时候我们pycharm会有一个优化的机制nagle,就是对于数据量小且发送间隔短的数据会一起发送给服务端,这是造成粘包的一种情况。那么我们在接收
的时候同样是从操作系统的缓存中取数据,那么每次如果最大值是recv(1024)的话,就会造成可能一次没办法取出来全部的发送过来的数据,同样造成粘包。
三 基于UDP的套接字通讯:
server_side
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) s.bind(('127.0.0.1',)) while True:
data,addr=s.recvfrom()
s.sendto(data.upper(),addr)
print(data,addr) s.close() client_side:
import socket
c=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) while True: c.sendto(b'hello',('127.0.0.1',8080))
c.sendto(b'world',('127.0.0.1',8080))
c.sendto(b'python',('127.0.0.1',8080))
data,addr=c.recvfrom(1024)
print(data.decode(),addr)
c.close()
基于tcp的下载文件,以及struct模块的应用。的更多相关文章
- 用c++开发基于tcp协议的文件上传功能
用c++开发基于tcp协议的文件上传功能 2005我正在一家游戏公司做程序员,当时一直在看<Windows网络编程> 这本书,把里面提到的每种IO模型都试了一次,强烈推荐学习网络编程的同学 ...
- 基于HTTP协议下载文件的实现
最近在开发文件下载的程序,该程序是基于HTTP开发的. 首先是了解了文件传输到客户端的大概格式,然后分析该格式,实现写入文件的功能. 自己构造的HTTP包如下: GET /*********.rar ...
- [php] thinkphp基于Http类 下载文件
http://blog.csdn.net/u010081689/article/details/49360937
- JAVA 基于TCP协议的一对一,一对多文件传输实现
最近老师给我们上了多线程和TCP和UDP协议,其中一个要求就是我们用JAVA协议一个基于TCP和UDP这两种协议的一对一文件上传和一对多文件上传. 然后我就开始分析TCP和UDP这两个协议的特点,发现 ...
- 基于TCP协议的大文件传输(粘包问题处理)
基于TCP的大文件上传服务端实现 # 服务端 # -*- coding: utf-8 -*- from socket import * import json, struct server = soc ...
- python tcp黏包和struct模块解决方法,大文件传输方法及MD5校验
一.TCP协议 粘包现象 和解决方案 黏包现象让我们基于tcp先制作一个远程执行命令的程序(命令ls -l ; lllllll ; pwd)执行远程命令的模块 需要用到模块subprocess sub ...
- 黏包-黏包的成因、解决方式及struct模块初识、文件的上传和下载
黏包: 同时执行多条命令之后,得到的结果很可能只有一部分,在执行其他命令的时候又接收到之前执行的另外一部分结果,这种显现就是黏包. 只有TCP协议中才会产生黏包,UDP协议中不会有黏包(udp协议中数 ...
- [转]python3之paramiko模块(基于ssh连接进行远程登录服务器执行命令和上传下载文件的功能)
转自:https://www.cnblogs.com/zhangxinqi/p/8372774.html 阅读目录 1.paramiko模块介绍 2.paramiko的使用方法 回到顶部 1.para ...
- 基于tcp协议的登录,文件上传和下载
[1]先登录,登录不成功循环登录,直到成功.登录成功后可以选择上传或者下载,上传有对应的文件,可选择上传哪个:下载有对应的文件,可选择下载哪个 [2]登录,上传,下载时最好设置状态码,客户端和 ...
随机推荐
- Reactor/Proactor的比较 (ZZ)
一般情况下,I/O 复用机制需要事件分享器(event demultiplexor [1.3]). 事件分享器的作用,即将那些读写事件源分发给各读写事件的处理者,就像送快递的在楼下喊: 谁的什么东西送 ...
- oauth 2.0 授权流程图
1.授权码模式(authorization code) 7 步 后面 拿到授权码以后,就是向 资源服务器请求资源了. 2.简化模式(implicit): 在上面的第4 步的返回中,已经包含了 acc ...
- Laravel $request添加数据或数据修改
laravel开发项目的时候,很多时候我们从$request里获取请求参数,今天在做项目的时候,遇到这样一个需求,就是请求参数到后台,后台需要根据判断重新给$request赋值,那如何去处理的 使用 ...
- JS判断字符串是否为空或是否全为空格
var test = " "; //为空或全部为空格 if (test.match(/^[ ]*$/)) { console.log("all space or empt ...
- file命令详解
Linux file命令 Linux file命令用于辨识文件类型. 通过file指令,我们得以辨识该文件的类型 用法: file [-bchikLNnprsvz0] [--apple] [--mim ...
- CentOS 7 firewalld vsftpd开放端口
开放FTP端口的方法: 暂时开放 ftp 服务 firewall-cmd --add-service=ftp 1 永久开放 ftp 服务 firewall-cmd --add-service=ftp ...
- 代码编辑器之sublime text
http://www.iplaysoft.com/sublimetext.html 1.特点: 中文乱码问题:另外,很多朋友反映表示打开中文会有乱码,其实是因为ST2本身只支持UTF-8编码,而我们常 ...
- Hiero的spreadsheet中添加tag属性列
Hiero在对剪辑线上的item进行管理的时候,往往会添加能多tag,而在管 理面板spreadsheet中却无法对tag进行查询,这是一件很麻烦的事,Hiero Development Guide中 ...
- chrome flash
chrome://settings/content/flash 在Chrome地址栏中输入:chrome://settings/content/flash,进入Flash设置,勾选允许网站运行flas ...
- sp_who, sp_who2和sp_who3
sp_who可以返回如下信息: (可选参数LoginName, 或active代表活动会话数)Spid (系统进程ID)status (进程状态)loginame (用户登 ...