我进行了端口轮播的练习,这意味着我需要构建一个服务器-客户端,服务器向客户端请求端口,然后他们开始侦听给定的端口,这就是我得到的循环错误,我不知道如何解决。
服务器:
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”
答案 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
也会自动发生),您再也不能将其用于connect
或bind
到其他地址/端口。>