面试题答案
一键面试实现步骤
- 导入必要的库:导入
asyncio
和socket
模块。 - 创建服务器套接字:使用
socket
模块创建一个TCP套接字,并绑定到指定的地址和端口,然后开始监听连接。 - 定义处理客户端请求的协程:在协程中,接受客户端连接,读取本地文本文件内容,将内容发送给客户端,最后关闭连接。
- 使用
asyncio
运行服务器:通过asyncio
的事件循环来启动服务器,使其能够处理多个并发连接。
关键代码
import asyncio
import socket
async def handle_connection(reader, writer):
try:
with open('local_file.txt', 'r') as file:
content = file.read()
writer.write(content.encode())
await writer.drain()
except FileNotFoundError:
writer.write(b'File not found')
await writer.drain()
finally:
writer.close()
async def start_server():
server = await asyncio.start_server(handle_connection, '127.0.0.1', 8888)
async with server:
await server.serve_forever()
if __name__ == "__main__":
asyncio.run(start_server())
在上述代码中:
handle_connection
协程处理每个客户端连接,负责读取文件内容并发送给客户端。start_server
协程创建并启动服务器,将handle_connection
协程关联到服务器,使其处理客户端连接。asyncio.run(start_server())
启动事件循环并运行服务器。注意:这里使用asyncio.start_server
替代了socket
模块手动处理连接部分,asyncio.start_server
内部已经结合了socket
底层操作并实现异步化。如果非要结合socket
模块,可以参考以下代码:
import asyncio
import socket
async def handle_connection(client_socket):
try:
with open('local_file.txt', 'r') as file:
content = file.read()
client_socket.sendall(content.encode())
except FileNotFoundError:
client_socket.sendall(b'File not found')
finally:
client_socket.close()
async def start_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('127.0.0.1', 8888))
server_socket.listen()
server_socket.setblocking(False)
while True:
client_socket, addr = await asyncio.get_running_loop().sock_accept(server_socket)
asyncio.create_task(handle_connection(client_socket))
if __name__ == "__main__":
asyncio.run(start_server())
此代码中,手动使用socket
模块创建套接字,设置为非阻塞模式,通过asyncio.get_running_loop().sock_accept
接受客户端连接,并为每个连接创建一个任务来处理。