繁体   English   中英

Python 2.7 Socket编程端口

[英]Python 2.7 Socket programming ports

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

服务器:

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行,在main中
server_socket.bind(('0.0.0.0',port))
AttributeError:'tuple'对象没有属性'bind'

在主函数中,执行以下操作:

(client_socket, server_socket) = server_socket.accept()

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

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

你应该做的是一些事情

(client_socket, client_connection_info) = server_socket.accept()

并相应地调整您的代码。

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

client_socket, client_addr = server_socket.accept()

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

您还应该close完成的套接字,这样就不会不断泄漏文件描述符。 这意味着每次从客户端收到新的端口号时,都应关闭客户端套接字侦听套接字,然后创建一个新的侦听套接字(并bindlisten ),然后接受新的客户端套接字。

总而言之,这将意味着重新调整服务器中的代码。 你需要将一个监听套接字的创建下拉到你的main中, while not done循环。

要记住的另一件事。 在客户端,在将端口号发送到服务器后,您正尝试connect到该新端口号。 但是,几乎可以肯定,在服务器有机会创建新的侦听套接字并绑定它之前,您的connect请求将到达服务器。 因此,您的客户端要么在尝试连接之前需要延迟一段时间,要么需要逻辑来重试connect一段时间。

编辑:
此外,您还必须在重新连接时在客户端创建新的套接字。 一旦流套接字绑定到端口( connect时也会自动发生),您永远不能使用它来bindconnect到不同的地址/端口。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM