繁体   English   中英

python中的UDP广播和自动服务器发现,TCP套接字不可用

[英]UDP broadcast and automatic server discovery in python, TCP socket unavailable

我正在python中开发一个反向shell应用程序,现在我正在尝试实现一个自动发现功能。 它应该如下工作:

  1. 服务器广播它侦听连接的IP /端口,并等待客户端。 如果没有客户端尝试在几秒钟内连接,它会再次广播(并重复直到连接)。
  2. 客户端尝试接收服务器的广播,并连接到通告的IP /端口。

广播工作正常,客户端接收IP /端口并成功连接,但是在使用连接的端口对后,我得到(服务器端):

socket.error:[Errno 35]资源暂时不可用

服务器端测试代码:

sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sckt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sckt.settimeout(2)
sckt.bind(('', 9999))
sckt.listen(5)

broadcastSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
broadcastSocket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
broadcastSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
while True:
    broadcastSocket.sendto(socket.gethostbyname(socket.getfqdn()) + ' ' + str(9999), ('<broadcast>', 8888))
    try:
        sock, address = sckt.accept()
        break
    except socket.timeout:
        pass
broadcastSocket.close()
sckt.settimeout(None)

sock.send('test')
# if I add time.sleep(1) here, it works, but I don't get why
# would sock be unavailable at first, but available a second later
print sock.recv(1) # this is where it fails
# note that it also fails with any recv buffer size, for instance 1024

你可能会问,为什么我想要接收1字节的数据呢? 我有一个算法,它以长度为前缀消息,接收器逐字节地读取这个前缀直到分隔符,这就是原因。 客户端测试代码:

broadcastSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
broadcastSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
broadcastSocket.settimeout(3)
broadcastSocket.bind(('', 8888))
while True:
    try:
        data = broadcastSocket.recv(1024)
        break
    except socket.timeout:
        pass
broadcastSocket.close()

sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sckt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sckt.connect((str(data.split()[0]), int(data.split()[1])))

print sckt.recv(1024)
sckt.send('lel')

如果我省略代码的整个广播和自动发现部分,只需手动输入服务器的IP /端口, print sock.recv(1)就不会失败。 有关问题的任何线索可能是什么?

在服务器代码sckt.settimeout(None)更改为sock.settimout(None)

你想拥有阻塞模式,而不是接受一个接受套接字。

这可确保sckt.recv等待来自客户端的传入消息。

PS sock.setblocking(1)完全一样

暂无
暂无

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

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