Python中的Netcat实现

44 投票
4 回答
106216 浏览
提问于 2025-04-15 17:03

我找到了这个链接,并把它当作我的基础,但一开始并没有正常工作。我的目标是把它当作一个包来使用,而不是一个命令行工具,所以我会根据这个目标来修改我的代码。

class Netcat:
    def __init__(self, hostname, port):
        self.hostname = hostname
        self.port = port
    def send(self, content):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.connect((self.hostname, self.port))
        self.socket.setblocking(0)
        result = '';
        read_ready, write_ready, in_error = select.select([self.socket], [], [self.socket], 5)
        if(self.socket.sendall(content) != None):
            return
        while(1):
            buffer = ''
            try:                
                buffer = self.socket.recv(128)
                while(buffer != ''):
                    result += buffer
                    try:
                        buffer = self.socket.recv(128)
                    except socket.error as err:
                        print (err, type(err))
                        buffer = ''
                if(buffer == ''):
                    break
            except socket.error as err:
                print (err, type(err))
            if(buffer == ''):
                break
        return result

当我给我的设备发送一个基本命令时,它会返回以下内容。

50PMA-019 Connection Open
Atten #1 = 63dB

我的代码读取了第一行,但接着就出现了一个错误,提示连接暂时不可用,结果没有读取到第二行。如果我把它改成阻塞模式,它就一直卡在那里,永远不会返回。有什么想法吗?

4 个回答

5

如果你不介意完全放弃那段代码,可以看看 scapy —— 它基本上是Python中处理数据包的瑞士军刀。你可以看看这个 互动教程,看看它是否符合你的需求。

如果你想要比数据包更高级的东西,twisted 是Python中进行网络编程的首选库……不过,学习起来有点难。

26

下面是一个在python3上可以运行的实现:

import socket
                                                                              
def netcat(host, port, content):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, int(port)))
    s.sendall(content.encode())
    s.shutdown(socket.SHUT_WR)
    while True:
        data = s.recv(4096)
        if not data:
            break
        print(repr(data))
    s.close()

这个代码可以用来把“内容”发送到一个“主机”,通过“端口”(这些都可以作为字符串输入)。

74

如果你只是用 nc,这样能行吗?

我觉得你可以试试简单一点的方法:

import socket

def netcat(hostname, port, content):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((hostname, port))
    s.sendall(content)
    s.shutdown(socket.SHUT_WR)
    while 1:
        data = s.recv(1024)
        if len(data) == 0:
            break
        print("Received:", repr(data))
    print("Connection closed.")
    s.close()

我加上了 shutdown 这个命令,因为你的设备可能在等你说你已经发送完数据了。(这听起来有点奇怪,但也是有可能的。)

撰写回答