43

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?

unholysampler
  • 17,141
  • 7
  • 47
  • 64

3 Answers3

72

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

Jason Orendorff
  • 42,793
  • 6
  • 62
  • 96
  • 2
    Adding the shutdown line to my original code made it work and I'll borrow from your code to trim down my code. – unholysampler Dec 15 '09 at 18:36
  • 1
    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. – Bob Ebert Mar 07 '16 at 17:25
  • Bob, you should consider clicking Ask Question and asking this one, if you haven't already. – Jason Orendorff Mar 11 '16 at 23:17
  • 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? – Cherry Wu Dec 17 '19 at 07:24
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 sting).

Regards

d0n
  • 311
  • 3
  • 4
  • 4
    I found I needed to add a `time.sleep(0.5)` before `shutdown` here, too. – tripleee Jan 29 '16 at 06:43
  • @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? – Poikilos Nov 19 '22 at 03:10
  • @Poiklos I can't possibly be expected to rembember that. Probably `nc` running on whichever MacOS version was dominant at the time. – tripleee Nov 19 '22 at 09:47
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.

Autoplectic
  • 7,566
  • 30
  • 30
  • 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. – unholysampler Dec 15 '09 at 18:08