Python 2.7套接字编程端口

时间:2018-08-28 08:57:57

标签: python python-2.7

我进行了端口轮播的练习,这意味着我需要构建一个服务器-客户端,服务器向客户端请求端口,然后他们开始侦听给定的端口,这就是我得到的循环错误,我不知道如何解决。

服务器:

import socket
import random

def main():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(('0.0.0.0', 1729))
    server_socket.listen(1)
    (client_socket, server_socket) = server_socket.accept()

    done = False
    while not done:
        port = client_socket.recv(4096)
        client_socket.send('i got the port' + port)
        port = int(port)

        if port != 1:
            server_socket.bind(('0.0.0.0', port))
            continue
        else:
            done = True


if __name__ == '__main__':
    main()

客户端:

import socket
import random


def main():
    print 'hi at anytime enter 1 to break the loop'
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect(('127.0.0.1', 1729))
    done = False

    while not done:
        port = client_socket.send(raw_input("enter port:"))
        data = client_socket.recv(4096)
        print data
        port = int(port)
        if port != 1:
            client_socket.connect(('127.0.0.1', port))
            continue
        else:
            done = True
    client_socket.close()


if __name__ == '__main__':
    main()

服务器的错误输出:

  

文件“ C:/Cyber​​/ServerFolder/ports_carrousel.py”,第18行,在主目录中
          server_socket.bind(('0.0.0.0',端口))
      AttributeError:“ tuple”对象没有属性“ bind”

2 个答案:

答案 0 :(得分:2)

在主要功能中,您需要执行以下操作:

(client_socket, server_socket) = server_socket.accept()

但是,server_socket.accept()实际上返回两个对象。第一个是套接字对象,第二个是包含(sourceIPString,sourcePort)的元组。

因此,通过使用上面概述的这一行代码,您实际上是在用元组对象覆盖server_socket。 请注意,稍后,在第18行中,您尝试访问套接字的“绑定”功能,但是使用对元组对象的引用,该功能未实现。

您应该做的是

(client_socket, client_connection_info) = server_socket.accept()

并相应地调整代码。

答案 1 :(得分:1)

这里有些错误。首先,accept返回一个2元组,其中包含新连接的套接字以及客户端的地址(它本身是2位元的IP地址和端口号)。它不会返回两个套接字。但是,您正在用第二个返回值覆盖server_socket变量。这没有任何意义,这就是解释器告诉您2元组没有bind属性的原因:它不是套接字对象。 accept调用应如下所示:

client_socket, client_addr = server_socket.accept()

接下来,在从客户端收到新的端口号之后,必须创建一个 new 套接字(不能重新使用相同的侦听套接字),然后bind将该新套接字插入新端口,然后是listen;最后,您可以从新的监听套接字中accept建立新的客户端连接。

您还应该使用close套接口,以免不断泄漏文件描述符。这意味着每次您从客户端收到新的端口号时,都应关闭客户端套接字,监听端口,然后创建一个新的监听端口(以及bind和{{1 }}),然后接受新的客户端套接字。

总而言之,这将意味着在服务器中显着重组代码。您需要将侦听套接字的创建下拉到主listen循环中。

另一件事要牢记。在客户端,将端口号发送到服务器后,您立即尝试使用while not done到该新端口号。但是,几乎可以肯定,您的connect请求将在服务器有机会创建新的监听套接字并绑定之前到达服务器。因此,您的客户端可能需要延迟一段时间才能尝试进行连接,或者需要具有逻辑以便在一段时间内重试connect

编辑:
另外,重新连接时,也必须在客户端上创建一个 new 套接字。将流套接字绑定到端口后(connect也会自动发生),您再也不能将其用于connectbind到其他地址/端口。

相关问题