简体   繁体   English

为什么在Python 3.4的循环中使用socket.connect()会停止工作?

[英]Why does socket.connect() stop working when used within a loop in Python 3.4?

I'm just starting to learn programming python, and have been following a tutorial for creating a simple port scanner in order to learn about programming sockets. 我刚刚开始学习python编程,并且一直在关注创建简单端口扫描程序的教程,以了解有关套接字编程的知识。 I'm able to make a successful connection to localhost when I manually enter all the code for a single iteration, however if I take the same code, and apply it within a for loop utilizing try/except, I immediately get exceptions for every port in the range, even when I know that some of the ports are open. 当我手动输入所有代码进行一次迭代时,我能够成功连接到本地主机,但是,如果我使用相同的代码,并使用try / except将其应用到for循环中,则我会立即获得每个端口的异常范围内,即使我知道某些端口已打开。 I believe that I've isolated the problem to socket.connect() because I've entered code below that that I know never gets executed. 我相信我已经将问题隔离到socket.connect(),因为我在下面输入了我永远都不会执行的代码。

I can enter the following code, and get a successful return: 我可以输入以下代码,并获得成功的回报:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(10)
port = 22
s.connect(('127.0.0.1', port))
s.send(b'test')
banner = s.recv(1024)
print(banner)
s.close()

returns: 返回:

b'SSH-2.0-OpenSSH_6.2\r\n'

Process finished with exit code 0

However, as soon as I take that code and move it into a for loop with the port number as the iterator, it stops working. 但是,一旦我获取该代码并将其移动到以端口号作为迭代器的for循环中,它便停止工作。

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(10)
for port in range(1,26):
    print("[+]Attempting to connect to : " + str(port))
    try:
      s.connect(('127.0.0.1', port))
      s.send(b'test')
      banner = s.recv(1024)
      s.close()
      if banner:
        print("Port " + port + "is Open: " + banner)
    except: print("[+]Port " + str(port) + " is closed")  

returns: 返回:

[+]Attempting to connect to : 1
[+]Port 1 is closed
[+]Attempting to connect to : 2
[+]Port 2 is closed
[+]Attempting to connect to : 3
[+]Port 3 is closed
....ETC....ETC....ETC....
[+]Attempting to connect to : 24
[+]Port 24 is closed
[+]Attempting to connect to : 25
[+]Port 25 is closed

Even though I KNOW port 22 is open and listening on localhost. 即使我知道端口22已打开并且正在localhost上侦听。 (ie I am able to ssh to 127.0.0.1 without issue). (即我能够ssh到127.0.0.1,没有问题)。 I have tried everything I can think of to no avail, including changing the data type of port to an int manually by using the internal int() function, I've tried the socket.connect_ex object, etc. I've also put code right below the socket.connect statement just to see if it shows up, which it never does. 我已经尝试了所有我能想到的一切,包括使用内部int()函数手动将端口的数据类型更改为int,尝试了socket.connect_ex对象,等等。我还放置了代码在socket.connect语句的正下方,只是查看它是否显示出来,而从未执行过。

The Zen of Python states: Python的禅宗指出:

Errors should never pass silently. 错误绝不能默默传递。
Unless explicitly silenced. 除非明确地保持沉默。

Only you have not silenced the error but instead just replaced it with a message that is non-descriptive of what actually happened: 只有您没有使错误消失,而只是将其替换为对实际发生的情况没有描述的消息:

>>> "Port" + 1
Traceback (most recent call last):
  File "<pyshell#15>", line 1, in <module>
    "Port "+1
TypeError: Can't convert 'int' object to str implicitly

is what you will get if opening port 1 worked, but after you close a socket you can't connect to anything else: 如果打开端口1会得到的结果是,但是在关闭套接字之后,您将无法连接到其他任何设备:

>>> a = socket.socket()
>>> a.close()
>>> a.connect(("www.python.com",80))
Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    a.connect(("www.python.com",80))
OSError: [Errno 9] Bad file descriptor

So you need to create a new socket inside the loop for it to work properly but most importantly: you need to limit the errors you catch: 因此,您需要在循环内创建一个新套接字,以使其正常工作,但最重要的是:您需要限制捕获的错误:

try:
    #if this is the only line you expect to fail, then it is the only line in the try
    s.connect(('127.0.0.1', port))
except ConnectionError: 
    #if a ConnectionError is the only one you expect, it is the only one you catch
    print("[+]Port " + str(port) + " is closed")
else: #if there was no error
    s.send(b'test')
    banner = s.recv(1024)
    s.close()
    if banner:
        print("Port " + port + "is Open: " + banner)

then you will see the actual errors you are getting instead of guessing what went wrong which is also against The Zen of Python : 然后您将看到实际的错误,而不是猜测哪里出了问题,这也不利于The Zen of Python

In the face of ambiguity, refuse the temptation to guess. 面对模棱两可的想法,拒绝猜测的诱惑。

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

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