[英]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
完成的套接字,这样就不会不断泄漏文件描述符。 这意味着每次从客户端收到新的端口号时,都应关闭客户端套接字和侦听套接字,然后创建一个新的侦听套接字(并bind
并listen
),然后接受新的客户端套接字。
总而言之,这将意味着重新调整服务器中的代码。 你需要将一个监听套接字的创建下拉到你的main中, while not done
循环。
要记住的另一件事。 在客户端,在将端口号发送到服务器后,您正尝试connect
到该新端口号。 但是,几乎可以肯定,在服务器有机会创建新的侦听套接字并绑定它之前,您的connect
请求将到达服务器。 因此,您的客户端要么在尝试连接之前需要延迟一段时间,要么需要逻辑来重试connect
一段时间。
编辑:
此外,您还必须在重新连接时在客户端创建新的套接字。 一旦流套接字绑定到端口( connect
时也会自动发生),您永远不能使用它来bind
或connect
到不同的地址/端口。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.