码迷,mamicode.com
首页 > 其他好文 > 详细

基于select类型多路IO复用,实现简单socket并发

时间:2018-05-23 22:15:54      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:empty   else   才有   name   tin   accept   情况下   程序   try   

还有很多缺限,如客户断开无限重复

以下转至老师博客:

server:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = "alex"
import select
import socket
import sys
import queue
server = socket.socket()
server.setblocking(0)
server_addr = (‘localhost‘,5000)
print(‘starting up on %s port %s‘ % server_addr)
server.bind(server_addr)
server.listen(5)

inputs = [server, ] #自己也要监测呀,因为server本身也是个fd
outputs = []
message_queues = {}

while True:
    print("waiting for next event...")
    readable, writeable, exeptional = select.select(inputs,outputs,inputs) #如果没有任何fd就绪,那程序就会一直阻塞在这里
    for s in readable: #每个s就是一个socket
        if s is server: #别忘记,上面我们server自己也当做一个fd放在了inputs列表里,传给了select,如果这个s是server,代表server这个fd就绪了,
            #就是有活动了, 什么情况下它才有活动? 当然 是有新连接进来的时候 呀
            #新连接进来了,接受这个连接
            conn, client_addr = s.accept()
            print("new connection from",client_addr)
            conn.setblocking(0)
            inputs.append(conn) #为了不阻塞整个程序,我们不会立刻在这里开始接收客户端发来的数据, 把它放到inputs里, 下一次loop时,这个新连接
            #就会被交给select去监听,如果这个连接的客户端发来了数据 ,那这个连接的fd在server端就会变成就续的,select就会把这个连接返回,返回到
            #readable 列表里,然后你就可以loop readable列表,取出这个连接,开始接收数据了, 下面就是这么干 的

            message_queues[conn] = queue.Queue() #接收到客户端的数据后,不立刻返回 ,暂存在队列里,以后发送

        else: #s不是server的话,那就只能是一个 与客户端建立的连接的fd了
            #客户端的数据过来了,在这接收
            data = s.recv(1024)
            if data:
                print("收到来自[%s]的数据:" % s.getpeername()[0], data)
                message_queues[s].put(data) #收到的数据先放到queue里,一会返回给客户端
                if s not  in outputs:
                    outputs.append(s) #为了不影响处理与其它客户端的连接 , 这里不立刻返回数据给客户端


            else:#如果收不到data代表什么呢? 代表客户端断开了呀
                print("客户端断开了",s)

                if s in outputs:
                    outputs.remove(s) #清理已断开的连接

                inputs.remove(s) #清理已断开的连接

                del message_queues[s] ##清理已断开的连接


    for s in writeable:
        try :
            next_msg = message_queues[s].get_nowait()

        except queue.Empty:
            print("client [%s]" %s.getpeername()[0], "queue is empty..")
            outputs.remove(s)

        else:
            print("sending msg to [%s]"%s.getpeername()[0], next_msg)
            s.send(next_msg.upper())


    for s in exeptional:
        print("handling exception for ",s.getpeername())
        inputs.remove(s)
        if s in outputs:
            outputs.remove(s)
        s.close()

        del message_queues[s]

  client:

__author__ = "alex"
import socket
import sys
messages = [ b‘This is the message. ‘,
             b‘It will be sent ‘,
             b‘in parts.‘,
             ]
server_address = (‘localhost‘, 5000)
# Create a TCP/IP socket
socks = [ socket.socket(socket.AF_INET, socket.SOCK_STREAM),
          socket.socket(socket.AF_INET, socket.SOCK_STREAM),
          ]
# Connect the socket to the port where the server is listening
print(‘connecting to %s port %s‘ % server_address)
for s in socks:
    s.connect(server_address)

for message in messages:

    # Send messages on both sockets
    for s in socks:
        print(‘%s: sending "%s"‘ % (s.getsockname(), message) )
        s.send(message)

    # Read responses on both sockets
    for s in socks:
        data = s.recv(1024)
        print( ‘%s: received "%s"‘ % (s.getsockname(), data) )
        if not data:
            print(sys.stderr, ‘closing socket‘, s.getsockname() )

  ...

基于select类型多路IO复用,实现简单socket并发

标签:empty   else   才有   name   tin   accept   情况下   程序   try   

原文地址:https://www.cnblogs.com/alex-hrg/p/9079474.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!