需求
- 创建一个TCP/Socket服务器接收客户端发送的信息并返回给客户端
- 以多线程方式实现接收客户端信息
- 将客户端发送的信息解码输出
思路分析
- 创建一个TCP/Socket服务端
- 写一个接收消息的方法,可以接收客户端消息并解码输出
- 服务端被动监听,每有一个客户端连接就创建一个子线程执行接收消息方法
单进程轮询实现并发服务器
#!/usr/bin/env python3
# coding=utf-8
from socket import *
def main():
# 1、创建socket
server_socket = socket(AF_INET, SOCK_STREAM)
# 2、设置端口复用
server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, True)
# 3、设置为非堵塞
server_socket.setblocking(False)
# 4、绑定端口
server_socket.bind(("", 8888))
# 5、设置为被动socket
server_socket.listen(32)
print("Listen...")
# 保存所有已连接的客户端
client_list = []
while True:
# 等待客户端的到来
try:
client_socket, client_addr = server_socket.accept()
except:
pass
else:
print("客户端:[{},{}]已连接上".format(client_addr[0], client_addr[1]))
# 设置连接上来的客户端为非堵塞
client_socket.setblocking(False)
client_list.append((client_socket, client_addr))
# 遍历所有客户端是否有数据发过来
for client_socket, client_addr in client_list:
try:
data = client_socket.recv(1024)
except:
pass
else:
if data:
print("[{},{}]>>{}".format(client_addr[0], client_addr[1], data.decode("utf-8")))
else:
client_socket.close()
client_list.remove((client_socket, client_addr))
print("客户端:[{},{}]已断开连接".format(client_addr[0], client_addr[1]))
if __name__ == "__main__":
main()
多线程实现并发服务器
#!/usr/bin/env python3
# coding=utf-8
from socket import *
from threading import Thread
def recv_data(client_socket, client_addr):
while True:
data = client_socket.recv(1024)
if data:
print("[{},{}]>>{}".format(client_addr[0], client_addr[1], data.decode("utf-8")))
client_socket.send(data)
else:
print("客户端:[{},{}]已断开连接!".format(client_addr[0], client_addr[1]))
break
client_socket.close()
def main():
# 1、创建socket
server_socket = socket(AF_INET, SOCK_STREAM)
# 2、设置端口复用
server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, True)
# 3、绑定端口
server_socket.bind(("", 8888))
# 4、设置为被动socket
server_socket.listen(64)
print("Listen...")
try:
while True:
# 5、等待客户端连接
client_socket, client_addr = server_socket.accept()
print("新客户:[{},{}]已连接".format(client_addr[0], client_addr[1]))
# 6、创建一个线程处理客户端的数据
t1 = Thread(target=recv_data, args=(client_socket, client_addr))
# 7、设置线程守护
t1.setDaemon(True)
# 8、启动线程
t1.start()
finally:
# 当为所有的客户端服务完成之后再进行关闭,表示不再接收新的客户端的连接
server_socket.close()
if __name__ == "__main__":
main()