ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python-select / tcp通信

2021-04-19 15:20:37  阅读:197  来源: 互联网

标签:socket python queues tcp server client wlist message select


在实际开发中,经常会遇到select 和 socket进行搭配使用,在此个人做一个小结

一. select函数

1 函数原型

readable, writeable, exceptionable = select.select(rlist, wlist, xlist,timeout)

入参的前三个是三个列表,代表要监听的列表,通常第一个是读列表, 第二个是写列表,第三个则是异常列表,第四个代表select阻塞的时间(s)

返回值也是三个列表,分别是是监听列表中发生改变的成员,例如 rlist中一共监听了100个socket,如果有2个socket接收到消息,则readable中就应该有2个成员

但是特别注意的是,wlist中的所有成员都会复制到writeable

2 函数的实际应用--tcp--server

该脚本可以实现多客户端连接进行交互

import socket
import select
import sys
# import queue
import Queue
import signal


def server_start(server_ip, sever_port):
    try:
        # create a server socket /tcp
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # reuse socket
        # bind the server socket
        server_socket.bind((str(server_ip), int(sever_port)))
        server_socket.setblocking(False)  # socket is non_blocking
        # set the max listen client number = 10 and start listen
        server_socket.listen(10)
    except socket.error as err:
        print("server start error, reason = " + str(err))
        sys.exit(1)

    rlist = [server_socket]  # put the server_socket to list
    wlist = []
    message_queues = {}  # store the message with clients and server
    client_queues = {}  # store the client's address
    while True:
        try:
            timeout = 3  # if no event occur, select function will be return
            readable, writeable, exceptionable = select.select(rlist, wlist, rlist, timeout)
            print("select again")
        except select.error as err:
            print("select module init error, reason = " + str(err))
            sys.exit(1)
        # handle the readable
        for s in readable:
            # new client is coming
            if s is server_socket:
                client_socket, client_address = s.accept()
                client_socket.setblocking(False)
                rlist.append(client_socket)
                message_queues[client_socket] = Queue.Queue()  # create a message queue for new client
                client_queues[client_socket] = client_address  # store the new client address
                print("new client is connecting, client is " + str(client_address))
            # new data is coming or client is disconnected
            else:
                try:
                    # receive data
                    data_buff = s.recv(1024)
                except socket.error as err:
                    print("receive data err!" + str(client_queues[s]))
                if data_buff:
                    print(str(client_queues[s]) + "coming data, data = " + str(data_buff))
                    message_queues[s].put(data_buff)  # put new data to message queue
                    if s not in wlist:  # update the wlist to handle the recived data
                        wlist.append(s)
                else:  # client is disconnected
                    print("a client is disconnected " + str(client_queues[s]))
                    del message_queues[s]
                    del client_queues[s]
                    rlist.remove(s)
                    if s in wlist:
                        wlist.remove(s)
                    if s in writeable:
                        writeable.remove(s)
        # handle the writeable
        for s in writeable:
            try:
                msg_que = message_queues.get(s)  # get the message queue
                if msg_que is not None:  # the queue is exist
                    while not msg_que.empty(): # handle the message until the queue is empty
                        msg = msg_que.get_nowait()  # get the msg from message queue
                        # do something....
                        s.send(msg + str(client_queues[s]))
                        print("send data, data = " + str(msg + str(client_queues[s])))
                    print("exit")
                    wlist.remove(s)  # no message in queue

            except Queue.Empty:  # client socket is disconnected
                wlist.remove(s)  # update the wlist
        # handle the exceptionable
        for s in exceptionable:
            print("error!" + "(" + str(client_queues[s]) + ")")
            rlist.remove(s)
            if s in wlist:
                wlist.remove(s)
            del message_queues[s]
            del client_queues[s]
            pass


if __name__ == '__main__':
    signal.signal(signal.SIGINT, quit)
    signal.signal(signal.SIGTERM, quit)
    server_start("10.74.133.94", "8080")
    while True:
        pass

 

标签:socket,python,queues,tcp,server,client,wlist,message,select
来源: https://www.cnblogs.com/victor1234/p/14667854.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有