Netcat implementation in Python
Asked Answered
A

4

44

I found this and am using it as my base, but it wasn't working right out of the box. My goal is also to treat it as a package instead of a command line utility, so my code changes will reflect that.

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

When I send a basic command to my device, it returns the following.

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

My code reads the first line, but then I get an error saying that the connection is temporarily unavailable and it does not get the second line. If I change it to blocking, it just blocks and never returns. Any thoughts?

Aeneous answered 15/12, 2009 at 17:1 Comment(0)
C
74

Does it work if you just use nc?

I think you should try something a little simpler:

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

I added the shutdown call because maybe your device is waiting for you to say you're done sending data. (That would be a little weird, but it's possible.)

Circumjacent answered 15/12, 2009 at 18:18 Comment(7)
Adding the shutdown line to my original code made it work and I'll borrow from your code to trim down my code.Aeneous
I have the problem where my mac os doesn't send packets until I shutdown the connection. Is there any ways around because the connection I have canno't be made again.Cuboid
Bob, you should consider clicking Ask Question and asking this one, if you haven't already.Circumjacent
The content here is an encoded string? If I have a .csv file contains multiple columns and needs to send the records, how can I use this netcat() function?Delphinus
ok, you know how 'nc' under bash will return a daemon response? how to get use the above function to grab that daemon response in python? thank you in advance.Drescher
@Drescher to ask a question, click the Ask Question button.Circumjacent
@Drescher Which shell you are using has no bearing on how nc behaves. Note, though, that there are multiple implementations with that name. When you ask your new question, you should probably elucidate on what you mean by "return a daemon response", and describe which OS you are on and how Netcat was installed (or if it was provided with the OS installation, like it is on MacOS, mention that).Ubangi
P
26

The following is a working implementation on 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()

It can be used to send "content" to a "host" on "port" (which all might be entered as string).

Perpend answered 4/1, 2015 at 16:17 Comment(4)
I found I needed to add a time.sleep(0.5) before shutdown here, too.Ubangi
@tripleee, Please say what exactly it did without that line you suggest, and what device was on the other end. Can anyone else confirm this?Odd
@Poiklos I can't possibly be expected to rembember that. Probably nc running on whichever MacOS version was dominant at the time.Ubangi
Perhaps notice also that data will be bytes; if you need it as a string, you need to .decode() it (probably with an explicit encoding, which you have to know in advance. Many beginners will blindly guess, and then wonder why 'utf-8' breaks with a UnicodeDecodeError when the data you receive isn't actually UTF-8, or wonder why you get mojibake when you assume it's Latin-1 or Windows-1252 but your guess is wrong).Ubangi
C
5

if you don't mind scrapping that code altogether, you might like to look at scapy -- it's basically the swiss army knife of packet tools in python. take a look at the interactive tutorial to see if it fits your needs.

if you'd like something higher-level than packets twisted is the go-to library for networking in python... unfortunately the learning curve is a tad steep.

Caldwell answered 15/12, 2009 at 17:56 Comment(1)
I'm not tied anything really. I just need a simple interface to let me send a few characters and receive back the response from the device. I'll check the links you gave me.Aeneous
I
-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
Ilianailine answered 29/9, 2023 at 10:1 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Melisma

© 2022 - 2024 — McMap. All rights reserved.