【问题标题】:Python chat client & Server sockets issuePython 聊天客户端和服务器套接字问题
【发布时间】:2019-09-16 21:33:33
【问题描述】:

我对 python 有点陌生,这是我第一次使用套接字,我正在尝试制作一个具有客户端和服务器的应用程序,用户可以在客户端中键入,它将被发送到然后将其发送给所有其他客户端的服务器。我让它处于工作状态,但每当我尝试发送第二条消息时,我总是收到一个错误'错误:[Errno 10058] 不允许发送或接收数据的请求,因为套接字已经在那个方向关闭了之前的关机通话”。我怎样才能做到这一点?

尝试在开始新套接字或发送新消息之前添加套接字关闭和关闭,再次尝试仅使用现有套接字,但都没有工作给我没有错误,但程序只是在发送到服务器时挂起。

服务器

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

def __init__():
    HOST = '0.0.0.0'    
    PORT = 50012
    print("Initialising..")
    print("Initialized.")
    print("Binding..")
    s.bind((HOST, PORT))
    print("Bound.")
    print("Listener started")

    __listen__(HOST, PORT)


def __broadcast__(list_clients, conn, addr, HOST, PORT):
    print("broadcasting")
    while 1:
        data = conn.recv(1024)
        if not data: break
        print "{} Recieved from {}".format(data, addr)
        for x in list_clients:
            conn.sendto(data, x)
            __listen__(HOST, PORT)


def __listen__(HOST, PORT):
    print("listening")
    s.listen(1)
    conn, addr = s.accept()
    list_clients=[]
    list_clients.append(addr)
    print 'Connected by', addr
    __broadcast__(list_clients, conn, addr, HOST, PORT)


def ext():
    conn.close()

def __main__():
    print("Initialising..")
    __init__()
    print("Initialized.")
    print("Listener starting..")
    __listen__()

__init__()

客户

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

def __init__():
    HOST = '127.0.0.1'
    PORT =  50012
    __connect__(HOST, PORT)

def __connect__(HOST, PORT):
    s.connect((HOST, PORT))
    __sendmessage__(HOST, PORT)

def __sendmessage__(HOST, PORT):
    s.sendall(raw_input("You $: "))
    while 1:
        data = s.recv(1024)
        print data
        __sendmessage__(HOST, PORT)

def __exit__():
    s.shutdown(0)
__init__()    





【问题讨论】:

    标签: python python-2.7 sockets networking chat


    【解决方案1】:

    您的服务器在每次调用sendto() 客户端后,都会递归调用__listen__()accept(),即。 e.它在发送每条消息后等待新的连接 - 这是行不通的。 服务器必须同时等待来自客户端的连接和数据;使用select.select() 很容易。将您的 __init__()__broadcast__()__listen__() 替换为

        from select import select
        HOST = '0.0.0.0'    
        PORT = 50012
        s.bind((HOST, PORT))
        s.listen(1)
        list_clients = []
        for reads in iter(lambda: select([s]+list_clients, [], [])[0], []):
            for ready in reads: # each time select reports something is ready
                if s == ready:  # accept new client if it's the server socket
                    conn, addr = s.accept()
                    list_clients.append(conn)   # store the connection socket
                    print 'connected by', addr
                else:           # data from a client
                    try: data = ready.recv(1024)
                    except socket.error: data = ''
                    if not data:                # client disconnected, remove
                        list_clients.remove(ready)
                        ready.close()
                        continue
                    print "{} received from {}".format(data, ready.getpeername())
                    print("broadcasting")
                    for x in list_clients: x.send(data)
    

    客户端也有类似的问题,不能同时等待套接字和终端输入。有关有效的客户端实现,请参阅Handle multiple requests with select 的此答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-10
      • 2018-08-08
      • 1970-01-01
      • 1970-01-01
      • 2016-11-07
      • 2015-06-27
      • 2020-03-25
      • 2016-08-03
      相关资源
      最近更新 更多