楼主: ZQZ520
1936 0

[网帖精选] Python网络编程释疑 [推广有奖]

  • 2关注
  • 49粉丝

院士

17%

还不是VIP/贵宾

-

威望
4
论坛币
-1176554 个
通用积分
6481.7282
学术水平
99 点
热心指数
203 点
信用等级
94 点
经验
31703 点
帖子
655
精华
7
在线时间
2457 小时
注册时间
2014-5-7
最后登录
2021-8-4

楼主
ZQZ520 在职认证  发表于 2014-5-19 10:07:57 |只看作者 |坛友微信交流群|倒序 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
看论坛上好多同学对第7周网络编程不甚理解,因此有必要把我的理解贴出来和大家分享一下,希望能帮助大家更好地理解。
帖子中有什么不足之处欢迎大家指正。

python网络编程难的地方不在网络,而在事件反馈机制。
关键要理解什么时候产生事件,以及事件反馈回来结果参数及其含义。
整个过程其实就是注册事件-》产生事件-》返回事件-》处理事件 的整个流程,下面我用老师课上的select例子来描述(通过注释描述)这个过程。

import socket
import select
import Queue

#服务端监听地址和端口
server=('127.0.0.1',2013)
#创建socket
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

#设置socket选项和监听过程
sock.setblocking(False)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.bind(server)
sock.listen(10)

#读事件的socket列表,这个很重要,不在这个列表中的socket得不到事件反馈通知,初始只有服务监听socket
rlists=[sock]
#写事件的socket列表
wlists=[]
#接收到的数据队列
msg_que={}
#等待超时20秒
timeout=20
#从后面逻辑看,while rlists相当于while True
while rlists:
"""
select过程就是等待网络事件的过程,分别是读、写和异常事件,这集中了注册事件、产生事件和返回事件的过程
注册事件: 是关注rlists(读),wlists(写),rlists(异常)中的socket列表
产生事件: 当客户端socket连接和发送、服务端向客户端socket写入、以及网络异常这些事件就会分别产生读、写和异常事件
返回事件: 当服务端接收到这些事件就返回相应的列表,分别对应rs,ws,es
如果在timeout时间内没有产生上述事件,也会返回,此时rs,ws,es均为空
"""
    rs,ws,es = select.select(rlists,wlists,rlists,timeout)
#这说明没有socket事件
    if not(rs or ws or es):
        print "timeout......"
        continue
#读事件,可能有多个socket产生读事件,s是读事件发生的socket
    for s in rs:
#这个很重要,s是服务监听socket,所以是连接请求事件
        if s is sock:
#接受客户端socket连接,产生负责和客户端socket进行一对一通讯的socket(就是conn)
            conn,addr=s.accept()
            print 'connet by ', addr
            conn.setblocking(False)
        #这个非常重要,如果不把conn加入rlists,那么该socket上的读写事件将得不到通知
            rlists.append(conn)
        #初始化conn的数据队列,后面读到数据就放入到这个队列中
            msg_que[conn]=Queue.Queue()
#这是socket读事件
        else:
        #读数据
            data=s.recv(1024)
           #接收到数据
            if data:
                print data
              #将读到的数据放入s的数据队列
                msg_que.put(data)
              #将s加入到wlists队列,如果没有这个,s上发生的写事件就得不到事件通知
                if s not in wlists:
                    wlists.append(s)
           #没有接收到数据,通常是客户端主动断开socket连接,此时要将s从wlists和rlists中移除,并关闭s,清除s的数据队列
            else:
                if s in wlists:
                    wlists.remove(s)
                rlists.remove(s)
                s.close()
                del msg_que
#写事件,可能有多个socket产生写事件,s是写事件发生的socket
    for s in ws:
        try:
        #获取数据队列中的读到的数据
            msg=msg_que.get_nowait()
        except Queue.Empty:
        #数据队列中没有数据
            print "msg empty"
            wlists.remove(s)
        else:
        #发送数据
            s.send(msg)

#异常事件, s是发生异常的socket
    for s in es:
        print "except",s.getpeername()
       #将s从rlists中移除
        if s in rlists:
            rlists.remove(s)
       #将s从wlists中移除
        if s in wlists:
            wlists.remove(s)
        s.close()
        del msg_que

sock.close()
print 'server sock closed'
复制代码

poll、epoll流程都是类似的,理解了这个,其它的应该也不在话下
推荐一篇经典e文,我还没来得及看。
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Python网络编程释疑 python 网络编程 blocking continue Python网络编程释疑 Python编程 Python




CDA数据分析交流群 217748971
您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-20 13:27