公司的设备需要做一个GPRS的测试
测试的时候将服务器端的时间写入到设备
这样一来测试了GPRS的功能,二是将最新的时间同步到了设备
设备端当然就是客户端了,那需要写一个支持高并发的服务器端
查了下asyncio是一个不错的库,不过这个对我来说没有必要(确切来说我不懂怎么样用哈哈哈哈)
所以就用selector做一个简单的支持高并发的服务端了
就和网络上大多数例子一样,如果你看了我下面的代码的话,献丑
当然下面需要写一个界面,当这个服务器端不论放在哪台电脑上都可以支持,界面端今天打算写完
先把主体记下来
'''
GPRS test server
'''
import selectors
import socket
from datetime import datetime
sel = selectors.DefaultSelector()
'''
accept在外部socket连接进来也就是收到EVENT_READ消息时候调用到
sock.accpet会获取到连接进来的套接字以及地址
这里的conn套接字和外面的socket套接字不是一个概念
这个套接字是用来传输数据用的,当然连接进来的套接字也要设置为非阻塞的
因为要在这里也实现异步操作,这里就是异步的读取
这里也将对应的读取函数注册到这个套接字上,
所以在读取的时候就会将要读取的内容从对应的套接字上接收回来
当然看到下面的read函数,在读取之后再反馈给对应的套接字一个字符串
最后再关闭这次连接
'''
def accept(sock,mask):
conn,addr = sock.accept()
print('accepted',conn,'from',addr)
conn.setblocking(False)
sel.register(conn,selectors.EVENT_READ,read)
def get_send_data_ready(recvdata):
char_pos = recvdata.find("##");
if char_pos == -1:
return "illegal string"
send_data = recvdata[0:char_pos + 2] + "UTCtime:";
print(send_data)
now = datetime.now()
print('data time now:')
print(now)
now_utc_time = ((str)((int)((datetime.now()).timestamp())))
print(now_utc_time)
send_data += now_utc_time;
return send_data
def read(conn,mask):
data = conn.recv(100).decode('utf-8')
if data:
#print('echoing',repr(data),'to',conn)
print("receive data = %s"%data)
send_data = get_send_data_ready(data)
print("send_data = %s"%send_data)
conn.send(send_data.encode('utf-8'))
else:
#print('closeing',conn)
print("close socket")
sel.unregister(conn)
conn.close()
sock = socket.socket()
sock.bind(('',1544))
sock.listen(1000)
sock.setblocking(False)
'''一旦在sock上有READ事件就调用accept函数'''
sel.register(sock,selectors.EVENT_READ,accept)
def loop():
while True:
events = sel.select()
#print(type(events))
#print(events)
'''
Here events is a list type.In events it can include many events,
every event include a iterator.you can print it
'''
print('events lenght = %d'%len(events))
for key,mask in events:
callback = key.data
callback(key.fileobj,mask)
if __name__ == '__main__':
loop()
这里用USR-TCP232-Test-V1.3.exe 测试程序测了下并发
在这个USR-TCP232-Test-V1.3.exe 设置为循环发送数据每1ms发送一次数据会看到events = sel.select()
这个events (list 类型)的长度是2,这里就发生了并发,能够很清楚的体现并发
这也就是这里for循环的作用
本人小白,语言简陋,难免疏漏,欢迎指正!