发布于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黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!