Python中的Netcat实现

44

我发现了这个,并将其用作我的基础,但是它并不能直接使用。我的目标也是将其作为一个包来处理而不是命令行实用程序,因此我的代码更改将反映出这一点。

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个回答

73

如果只使用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 调用,因为也许您的设备正在等待您说您已经完成发送数据。(这有点奇怪,但是可能发生。)


2
将关闭行添加到我的原始代码中使其工作,我将借鉴您的代码来简化我的代码。 - unholysampler
1
我遇到了一个问题,我的Mac OS在关闭连接之前不会发送数据包。有没有什么解决方法,因为我无法重新建立这个连接。 - Bob Ebert
Bob,如果你还没有这样做的话,你应该考虑点击“提问”并询问这个问题。 - Jason Orendorff
这里的 content 是一个编码字符串吗?如果我有一个包含多列并需要发送记录的 .csv 文件,我该如何使用这个 netcat() 函数? - Cherry Wu

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()

它可用于将“内容”发送到“主机”的“端口”(所有这些可能被输入为字符串)。

问候


4
我发现我需要在这里添加 time.sleep(0.5),然后再执行 shutdown - tripleee
@tripleee,请说明一下它在没有你建议的那行代码的情况下具体做了什么,另一端是什么设备。还有其他人可以确认吗? - Poikilos
@Poiklos 我不可能指望自己记得那些细节。可能是在当时占主导地位的任何 MacOS 版本上运行的 nc - tripleee

5
如果您不介意完全放弃那段代码,您可能会喜欢看一下scapy——它基本上是Python中数据包工具的瑞士军刀。请查看交互教程,看看它是否符合您的需求。
如果您需要比数据包更高级的东西,Twisted是Python网络编程的首选库……不幸的是,学习曲线有点陡峭。

1
我并没有特别的限制。我只需要一个简单的接口,让我发送一些字符并从设备接收响应即可。我会查看你给我的链接。 - unholysampler

-2
import socket
import codecs
import subprocess

i = 0
sock = socket.socket()
host = ''
port = 
sock.connect((host, port))

while i != 20003:
  data = sock.recv(1024)
  print(data)
  data = codecs.escape_decode(data)[0].decode('unicode-escape')
  print(data)
  print(data.split())
  a = data.split()
  i +=1

你的回答可以通过提供更多的支持性信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的回答是否正确。你可以在帮助中心找到有关如何撰写好回答的更多信息。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接