程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

自学python实例_从tcp服务器简单下载一下文件的实例

发布于2020-04-04 17:48     阅读(1349)     评论(0)     点赞(21)     收藏(3)


想象一下,我们平时下文件的时候和在qq上聊天的时候,有什么异同呢?都是接收文件是吧?只是一个小一点,一个大一点,那么如果我们的文件变成很小,是不是可以认为也是聊天的一种形式呢?
自学python实例_tcp服务器
自学python实例_udp聊天窗口
这上面是之前写的,分别是用tcp和udp实现的一些简单的聊天窗口!
那么今天,我们改进一下,我们对tcp服务器来下载一个文件!
向上代码!

import socket
def send_file_2_client(new_client_socket, client_addr):	
	# 1. 接收客户端 需要下载的文件名
	file_name = new_client_socket.recv(1024).decode("utf-8")
	print("客户端(%s)需要下载的文件是: %s" % (str(client_addr), file_name))
	file_content = None
	# 2. 打开这个文件, 读取数据
	try:
		f = open(file_name, "rb")
		file_content = f.read()
		f.close()
	except Exception as ret:
		print("没有要下载的文件 %s" % file_name)
	# 3. 发送文件的数据给客户端
	if file_content:
		#new_client_socket.send("发送完毕".encode("utf-8"))
		new_client_socket.send(file_content)
def main():
	# 1. 创建套接字
	tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	# 2. 绑定本地信息
	tcp_server_socket.bind(("",7799))
	# 3. 设为被动
	tcp_server_socket.listen(128)
	while True:
		# 4. 等等对方进来
		new_client_socket, client_addr = tcp_server_socket.accept()
		# 5. 发送数据
		send_file_2_client(new_client_socket, client_addr)
		# 5. 关闭套接字
		new_client_socket.close
	cp_server_socket.close()
if __name__ == "__main__":
	main()

因为代码不是长,所有减少了一些缩进,因此没有完全遵循PEP8编码规范!
创建套节字…绑定…设监听…接堵塞…这个跳过,是基本的.
主要说 def send_file_2_client(new_client_socket, client_addr):这个函数,注意里面,我们打开文件使用了try是为什么呢?
是保证我们文件能正常打开并且写入,如果不成功,会告诉客户端没有要下载的文件.我们想象一下,如果没有try当我们在读写过程中,程序突然奔溃了,那么就不会调用f.close(),会导致这个文件占我们内存,注意了我们最多可以打开1024个文件,如果打开了很多文件,并且没有关闭,那么就会造成系统的奔溃!!
处理使用try之外,我们还可以使用 with 上下文管理器!!

with open("file_name, "rb") as f:
	f.write("file_content")

将上面替换成这个就可以了!使用with时,当程序突然奔溃的时候,或者结束了,都会主动调用f.close()
那么它是如何实现的呢,我们简单模拟一下:

class File():
	def __init__(self, file_name, mode):
		self.file_name = file_name
		self.mode = mode
	def __enter__(self):
		print("entering")
		self.f = open(sekf.file_name, self.mode)
		return self.f
	def __exit__(self, *args):
		print("exit")
		self.f.close()

内部可以大致模拟成这样,当出问题的时候,会主动调用类方法__exit___()
当然,上下文管理器还有另一种方式,使用contextmanager的装饰器来实现,这里我简单列举一下代码

from contextlib import contextmanager

@contextmanager
def my_open(path, mode):
	f = open(path, mode)
	yield f
	f.close()

通过yield将函数分成了两个部分,yield之前的语句是__enter__方法中执行的,yield之后的语句是__exit__方法中执行的,紧跟着的值是这个函数的返回值!

原文链接:https://blog.csdn.net/qq_42223962/article/details/105284908



所属网站分类: 技术文章 > 博客

作者:以拯救苍生己任

链接:https://www.pythonheidong.com/blog/article/304938/684f6f9ae1a3591e3b0d/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

21 0
收藏该文
已收藏

评论内容:(最多支持255个字符)