【问题标题】:error when trying to connect to server for next the connection using sockets in python尝试在 python 中使用套接字连接到服务器以进行下一个连接时出错
【发布时间】:2014-01-09 22:00:09
【问题描述】:

我正在学习使用 python 进行套接字编程。我的第一个任务是编写一个client.py 和一个server.py。 clientserver 发送消息。 server每次都会收到16 bytes的消息。在它收到整个消息后,它会将相同的消息发送回client。 所以很简单。服务器积压为1。服务器将消息发送给客户端后,与客户端的连接关闭,服务器应该打开以接收新连接。 我当前的代码在最后一步失败。未打开接收新连接。它正在抛出错误。我什至发现了错误。但我不知道如何解决这个问题。

错误来自 server.py,因为我调用了sock.accept(),但我已经关闭了sock。 让我解释一下我的 server.py 代码:我有两个 while loopsouter loop 查找新连接,inner loop 查找来自连接的处理请求,即它只是接收数据,等到所有内容都接收完毕,然后将其发送回客户端,最后关闭连接。

我被要求不要改变两个while loops 的结构,而只是实现它们。 对此有任何想法或想法:

client.py

import socket
import sys


def client(msg, log_buffer=sys.stderr):
    server_address = ('localhost', 10000)
    sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.IPPROTO_IP)
    sock.connect(server_address)
    print >>log_buffer, 'connecting to {0} port {1}'.format(*server_address)
    try:
        print >>log_buffer, 'sending "{0}"'.format(msg)
        sock.sendall(msg)
        chunk = ''
        done=False;
        while not done:
            chunk+=sock.recv(16)
            if chunk==msg:
                done=True

        print >>log_buffer, 'received "{0}"'.format(chunk)
    finally:
        print >>log_buffer, 'closing socket'
        sock.close()


if __name__ == '__main__':
    if len(sys.argv) != 2:
        usg = '\nusage: python echo_client.py "this is my message"\n'
        print >>sys.stderr, usg
        sys.exit(1)

    msg = sys.argv[1]
    client(msg)

Server.py

import socket
import sys


def server(log_buffer=sys.stderr):
    # set an address for our server
    address = ('127.0.0.1', 10000)
    sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.IPPROTO_IP)
    sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)


    # log that we are building a server
    print >>log_buffer, "making a server on {0}:{1}".format(*address)

    sock.bind(address)
    sock.listen(1)

    try:
        # the outer loop controls the creation of new connection sockets. The
        # server will handle each incoming connection one at a time.
        while True:
            print >>log_buffer, 'waiting for a connection'

            conn,add=sock.accept()
            addr=(conn,add)
            try:
                print >>log_buffer, 'connection - {0}:{1}'.format(*addr)

                # the inner loop will receive messages sent by the client in 
                # buffers.  When a complete message has been received, the 
                # loop will exit
                data = ''
                while True:

                    recvdata=conn.recv(16)
                    print recvdata
                    data+=recvdata
                    print >>log_buffer, 'received "{0}"'.format(data)
                    print >>log_buffer, "len of received data: {0}".format(len(recvdata))
                    if len(recvdata)<16:
                        print >>log_buffer,"sending data"
                        conn.sendall(data)
                        break
                conn.close()


            finally:

                sock.close()


    except KeyboardInterrupt:

        sock.close()


if __name__ == '__main__':
    server()
    sys.exit(0)

我在另一个终端中运行python server.py in one terminal andpython client.py "这是第一条消息。发回给我"`。客户端连接按预期正常丢失。但我在服务器端(接近尾声)收到以下错误:

making a server on 127.0.0.1:10000
waiting for a connection
connection - <socket._socketobject object at 0x100849c20>:('127.0.0.1', 50626)
sairam hopefully
received "sairam hopefully"
len of received data: 16
 this works lets
received "sairam hopefully this works lets"
len of received data: 16
 c
received "sairam hopefully this works lets c"
len of received data: 2
sending data
waiting for a connection
Traceback (most recent call last):
  File "echo_server.py", line 89, in <module>
    server()
  File "echo_server.py", line 39, in server
    conn,add=sock.accept()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 202, in accept
    sock, addr = self._sock.accept()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 170, in _dummy
    raise error(EBADF, 'Bad file descriptor')
socket.error: [Errno 9] Bad file descriptor

【问题讨论】:

    标签: python sockets client-server


    【解决方案1】:

    您将在 while 循环中关闭 sock。不要那样做。 sock 是您的持久服务器套接字,它需要保持打开状态以侦听新连接。 conn 是您的临时套接字,它只需要在单个连接的长度内保持打开状态。

    每次连接后关闭conn,当服务器需要终止时关闭sock

    更简单地说,替换这些行:

           finally:
                sock.close()
    

           finally:
                conn.close()
    

    【讨论】:

    • 是的,我是这么认为的。但我的说明在下面说# TODO: When the inner loop exits, this 'finally' clause will # be hit. Use that opportunity to close the socket you # created above when a client connected. Replace the # call to pass`,这只是为了防止#语法问题`
    • 在这种情况下,将sock.close() 替换为conn.close()。它们的关键在于指令:“关闭您在上面创建的套接字当客户端连接时”。在你的情况下,这是conn,而不是sock
    • 已解决,但我现在得到了socket.error: [Errno 48] Address already in use,尽管我有sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 可以重复使用地址?
    • 这是一个新问题。
    【解决方案2】:

    您要做的是一个简单的回显服务器,我相信您可以更简单地实现它。

    服务器:

    import socket 
    
    host = '' 
    port = 50000 
    backlog = 5 
    size = 1024 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    s.bind((host,port)) 
    s.listen(backlog) 
    while 1: 
        client, address = s.accept() 
        data = client.recv(size) 
        if data: 
            client.send(data) 
        client.close()
    

    客户:

    import socket 
    
    host = 'localhost' 
    port = 50000 
    size = 1024 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    s.connect((host,port)) 
    s.send('Hello, world') 
    data = s.recv(size) 
    s.close() 
    print 'Received:', data
    

    【讨论】:

      猜你喜欢
      • 2020-09-11
      • 1970-01-01
      • 2017-07-08
      • 2019-06-25
      • 1970-01-01
      • 1970-01-01
      • 2012-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多