请教关于 python 简单的 socket 服务器端的问题

2015-06-01 23:34:15 +08:00
 wowpanda

我在做一个简单的数据库,现在想实现通过网络来访问数据库。从客户端传送数据到服务器端,然后服务器端执行相应的操作。
我是建立一个socket,然后服务器开始无限循环,每次接收一个连接就开一个线程,然后由这个线程去操作数据库。
请问这个线程去操作数据库这一步要怎么做呢?
也是 while True:
data=socket.recv(maxsize)
result=database_operation(data)
socket.send(result)
这个思路吗? 这里的maxsize怎么设置?recv是阻塞的,如果客户端发送数据频率高的话,会出现客户端发送过来的数据成了一团浆糊啊。
另外,怎么保持连接的时间?因为客户端操作的时间间隔肯定会很长,这个线程一直要这样循环下去吗?
ps:渣渣基础不好,求聚聚们轻喷。

3439 次点击
所在节点    Python
15 条回复
ryd994
2015-06-02 02:13:18 +08:00
你可以参考标准库 https://docs.python.org/2/library/socketserver.html
CPython源码网上有
你需要实时性的话就不要阻塞,反复查然后判断有没有数据,设置socket选项即可
tcp连接一般不需要特意保持,只要不关闭文件符就会一直开着。对于部分防火墙路由器可能需要keepalive,同样是设置socket选项即可
ryd994
2015-06-02 02:15:09 +08:00
另外你这样性能估计不好,需要性能的话要用epoll/gevent之类的
clino
2015-06-02 07:19:12 +08:00
建议用 http 更好
wowpanda
2015-06-02 09:58:06 +08:00
@ryd994
我查了一些epoll的资料,大致思路是:
while True:
if event & select.EPOLLIN:
data=connections[fileno].recv(maxsize)
result=database_operation(data)
epoll.modify(fileno, select.EPOLLOUT)
elif event & select.EPOLLOUT:
connections[fileno].send(result)
epoll.modify(fileno, select.EPOLLIN)
请问这么做,有没有什么问题?
wowpanda
2015-06-02 09:58:31 +08:00
@clino 用requests库来做?
clino
2015-06-02 10:09:33 +08:00
@wowpanda 我是说用提供 http api 的方式,客户端以访问 http api 的方式来调用服务端的服务
这样你的服务端程序只要考虑处理 request返回 response,并发调度之类的可以中间放一个nginx之类的web服务器来做
mulog
2015-06-02 10:13:40 +08:00
> 这里的maxsize怎么设置?recv是阻塞的,如果客户端发送数据频率高的话,会出现客户端发送过来的数据成了一团浆糊啊。

不会啊 你要用裸 socket 做的话肯定得自定一个简单协议 做好 message 之间的分割就好了
clino
2015-06-02 10:19:53 +08:00
或者如果web方面完全无基础可以先不考虑我的建议

上面gevent的建议,这里有简单例子: http://xlambda.com/gevent-tutorial/#server
gevent对于并发多io高的情况,因为是用协程方式实现的有占用资源较少支持并发较高的优点
wowpanda
2015-06-02 10:32:48 +08:00
@clino http api,我的理解是,用tornado库,访问一个url,然后返回数据
clino
2015-06-02 10:38:32 +08:00
@wowpanda 随便找个web框架就行,只是提供api估计都比较简单都差不多,如果涉及到其他方面差别就比较大了
另外像tornado这种本身是异步的所以对高并发本身支持得应该就比较好,像我用的uliweb则可以用gevent方式部署
fangjinmin
2015-06-02 12:47:23 +08:00
用epoll吧,epoll的效率更高。
zenliver
2015-06-02 16:00:13 +08:00
tornado有个tcpserver, 拿来用啊, 自己瞎捣鼓什么
ryd994
2015-06-03 02:41:48 +08:00
@wowpanda epoll或者gevent的库很多啊,比如greenlet之类的,基本上用法都是直接import代替原版就可
cloudzhou
2015-06-03 10:16:23 +08:00
使用 gevent
Karblue
2015-06-03 11:27:04 +08:00
epoll & iocp 同步操作肯定效率低

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/195409

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX