• 异步select


    server coding:

      1 #!/usr/bin/python
      2 # -*- coding: utf-8 -*-
      3 
      4 import select
      5 import socket
      6 import sys
      7 import Queue
      8 
      9 # Create a TCP/IP socket
     10 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     11 server.setblocking(False)
     12 
     13 # Bind the socket to the port
     14 server_address = ('localhost',1000)
     15 print >>sys.stderr, 'starting up on %s port %s'%server_address
     16 server.bind(server_address)
     17 
     18 # Listen for incoming connections
     19 server.listen(5)
     20 
     21 # Sockets from which we expect to read
     22 inputs = [server]
     23 
     24 # Sockets to which we expect to write
     25 outputs = []
     26 
     27 # Outgoing message queues (socket:Queue)
     28 message_queues = {}
     29 
     30 while True:
     31     # Wait for at least one of the sockets to be ready for processing
     32     print >>sys.stderr, '
    waiting for the next event'
     33     #分别筛选出可接收消息的sockets、等待发送消息的sockets、和中途出错的sockets。
     34     #其中exceptional为了把所有可接收消息的sockets都遍历到,所以要从inputs列表中读取。
     35     readable, writable, exceptional = select.select(inputs,outputs,inputs)
     36 
     37     # Handle inputs
     38     for s in readable:
     39         #第一种情况,创建一个待接收消息的socket放入inputs
     40         if s is server:
     41             # A "readable" server socket is ready to accept a connection
     42             connection, client_address = s.accept()
     43             print >>sys.stderr, 'new connection from', client_address
     44             connection.setblocking(0)
     45             inputs.append(connection)
     46             
     47             # Give the connection a queue for data we want to send
     48             message_queues[connection] = Queue.Queue()
     49             
     50         #第二种情况,在后续循环中,已经添加到inputs中的sockets已经不是readable了,所以
     51         #要进行接收消息,消息存在message_queues中,并把该socket添加到outputs。
     52         else:
     53             data = s.recv(1024)
     54             if data:
     55                 # A readable client socket has data
     56                 print >>sys.stderr, 'receieved "%s" from %s'%(data.upper(),s.getpeername())
     57                 message_queues[s].put(data)
     58                 # Add output channel for response,添加到待发送消息列表
     59                 if s not in outputs:
     60                     outputs.append(s)
     61         
     62             #第三种情况就是这个客户端已经断开了,
     63             #所以你再通过recv()接收到的数据就为空了,
     64             #所以这个时候你就可以把这个跟客户端的连接关闭了。
     65             else:
     66                 print >>sys.stderr, 'closing',client_address,'after reading no data'
     67                 if s in outputs:
     68                     outputs.remove(s)#既然客户端都断开了,我就不用再给它返回数据了,所以这时候如果这个客户端的连接对象还在outputs列表中,就把它删掉
     69                 inputs.remove(s)#inputs中也删除掉
     70                 s.close()#把这个连接关闭掉
     71                 
     72                  # Remove message queue
     73                 del message_queues[s]
     74     
     75     # Handle outputs
     76     for s2 in writable:
     77         try:
     78             next_msg = message_queues[s2].get_nowait()
     79         #没有消息了
     80         except Queue.Empty:
     81             # No messages waiting so stop checking for writability.
     82             print >>sys.stderr,'output queue for',s2.getpeername(),'is empty'
     83             outputs.remove(s2)
     84         #发送消息
     85         else:
     86             print >>sys.stderr, 'sending "%s" to %s'%(next_msg,s2.getpeername())
     87             s2.send(next_msg)
     88     
     89     # Handle "exceptional conditions"
     90     for s3 in exceptional:
     91         print >>sys.stderr, 'handling exceptional condition for ',s3.getpeername()
     92         # Stop listening for input on the connection
     93         inputs.remove(s3)
     94         if s3 in outputs:
     95             outputs.remove(s3)
     96         s3.close()
     97         
     98         #Remove message queue
     99         del message_queues[s3]
    100 
    101                 
    102             

    client coding

     1 # -*- coding: utf-8 -*-
     2 """
     3 Created on Sun Oct 23 14:49:20 2016
     4 
     5 @author: fuzzier
     6 """
     7 
     8 import sys
     9 import socket
    10 
    11 messages = ['This is the message.',
    12             'It will be sent',
    13             'in parts.'
    14             ]
    15 server_address = ('localhost',1000)
    16 
    17 # Create a TCP/IP socket,创建两个客户端
    18 socks = [socket.socket(socket.AF_INET,socket.SOCK_STREAM),
    19          socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    20          ]
    21 
    22 # Connect the socket to the port where the server is listening
    23 print >>sys.stderr, 'connecting to %s port %s'%server_address
    24 for s in socks:
    25     s.connect(server_address)
    26 
    27 for message in messages:
    28     
    29     # Send messages on both sockets
    30     for s2 in socks:
    31         print >>sys.stderr, '%s:sending "%s"'%(s2.getsockname(),message)
    32         s2.send(message)
    33     
    34     #Read responses on both sockets
    35     for s3 in socks:
    36         data = s3.recv(1024)
    37         print >>sys.stderr, '%s: received "%s"' % (s3.getsockname(), data.upper())
    38         if not data:
    39             print >>sys.stderr,'closing socket',s3.getsockname()
    40             s3.close()

    原理图:

    运行结果:

  • 相关阅读:
    @configuration 和 @bean
    js中关键字 const , let , var 的用法区别
    springboot+vue项目demo地址
    快速开发框架下载地址(github)
    搭建vue项目并启动vue项目
    export default{} 和 new Vue()都是什么意思
    反向代理
    [转]python类方法
    linux中waitpid及wait的用法
    mount
  • 原文地址:https://www.cnblogs.com/fuzzier/p/5990218.html
Copyright © 2020-2023  润新知