Basic socket interfaces¶
- class nclib.netcat.Netcat(connect=None, sock=None, listen=None, sock_send=None, server=None, udp=False, ipv6=False, raise_timeout=False, raise_eof=False, retry=0, loggers=None, verbose=0, log_send=None, log_recv=None, log_yield=False, echo_headers=True, echo_perline=True, echo_hex=False, echo_send_prefix='>> ', echo_recv_prefix='<< ')[source]¶
This is the main class you will use to interact with a peer over the network! You may instantiate this class to either connect to a server, listen for a one-off client, or wrap an existing sock/pipe/whatever.
One of the following must be passed in order to initialize a Netcat object:
- Parameters:
connect – the address/port to connect to
listen – the address/port to bind to for listening
sock – a python socket, pipe, file, etc to wrap
For
connect
andlisten
, they accept basically any argument format known to mankind. If you find an input format you think would be useful but isn’t accepted, let me know :PAdditionally, the following options modify the behavior of the object:
- Parameters:
sock_send –
If this is specified, this Netcat object will act as a multiplexer/demultiplexer, using the “normal” channel for receiving and this channel for sending. This should be specified as a python socket or pipe object.
Warning
Using
sock_send
will cause issues if you pass this object into a context which expects to be able to use its.fileno()
.udp – Set to True to use udp connections when using the connect or listen parameters
ipv6 – Force using ipv6 when using the connect or listen parameters
retry – The number of times to retry establishing a connection after a short (200ms) sleep if it fails.
raise_timeout – Whether to raise a NetcatTimeout exception when a timeout is received. The default is to return any buffered data and set
self.timed_out
= Trueraise_eof – Whether to raise a NetcatEOF exception when EOF is encountered. The default is to return any buffered data and set
self.eof = True
loggers – A list of Logger objects to consume socket events for logging.
The following options can be used to configure default loggers:
- Parameters:
log_send – Pass a file-like object open for writing and all data sent over the socket will be written to it.
log_recv – Pass a file-like object open for writing and all data recieved from the socket will be written to it.
verbose – Set to True to cause a log of socket activity to be written to stderr.
echo_headers – Controls whether stderr logging should print headers describing network operations and exceptional conditions.
echo_perline – Controls whether stderr logging should treat newlines as record separators.
echo_hex – Controls whether stderr logging should produce a hexdump.
echo_send_prefix – A prefix to print to stderr before each logged line of sent data.
echo_recv_prefix – A prefix to print to stderr before each logged line of received data.
log_yield – Control when logging messages are generated on recv. By default, logging is done when data is received from the socket, and may be buffered. By setting this to True, logging is done when data is yielded to the user, either directly from the socket or from a buffer. This affects both stderr and tee logging.
Any data that is extracted from the target address will override the options specified here. For example, a url with the
http://
scheme will go over tcp and port 80.You may use this constructor as a context manager, i.e.
with nclib.Netcat(...) as nc:
, and the socket will be automatically closed when control exits the with-block.Example 1: Send a greeting to a UDP server listening at 192.168.3.6:8888 and wait for a response. Log the conversation to stderr as hex.
>>> nc = nclib.Netcat(('192.168.3.6', 8888), ... udp=True, verbose=True, echo_hex=True) ======= Connected to ('localhost', 8888) ======= >>> nc.send(b'\x00\x0dHello, world!') ======= Sending 15 bytes ======= >> 000000 00 0D 48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 |..Hello, world! | >>> response = nc.recv() ======= Receiving at most 4096 bytes ======= << 000000 00 57 68 65 6C 6C 6F 20 66 72 69 65 6E 64 2E 20 |.Whello friend. | << 000010 74 69 6D 65 20 69 73 20 73 68 6F 72 74 2E 20 70 |time is short. p| << 000020 6C 65 61 73 65 20 74 6F 20 6E 6F 74 20 77 6F 72 |lease to not wor| << 000030 72 79 2C 20 79 6F 75 20 77 69 6C 6C 20 66 69 6E |ry, you will fin| << 000040 64 20 79 6F 75 72 20 77 61 79 2E 20 62 75 74 20 |d your way. but | << 000050 64 6F 20 68 75 72 72 79 2E |do hurry. | >>> nc.send(b'\x00\x08oh no D:') ======= Sending 10 bytes ======= >> 00000F 00 | .| >> 000010 08 6F 68 20 6E 6F 20 44 3A |.oh no D: |
Example 2: Listen for a local TCP connection on port 1234, allow the user to interact with the client. Log the entire interaction to log.txt.
>>> logfile = open('log.txt', 'wb') >>> nc = nclib.Netcat(listen=('localhost', 1234), log_send=logfile, log_recv=logfile) >>> nc.interact()
- __init__(connect=None, sock=None, listen=None, sock_send=None, server=None, udp=False, ipv6=False, raise_timeout=False, raise_eof=False, retry=0, loggers=None, verbose=0, log_send=None, log_recv=None, log_yield=False, echo_headers=True, echo_perline=True, echo_hex=False, echo_send_prefix='>> ', echo_recv_prefix='<< ') None [source]¶
- property closed: bool¶
Whether the socket has been closed by the user (not the peer).
- interact(insock=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'>, outsock=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>) None [source]¶
Connects the socket to the terminal for user interaction. Alternate input and output files may be specified.
This method cannot be used with a timeout.
Aliases: interactive, interaction
- recv(n: int = 4096, timeout: float | int | Literal['default'] | None = 'default') bytes [source]¶
Receive at most n bytes (default 4096) from the socket
Aliases: read, get
- recv_all(timeout: float | int | Literal['default'] | None = 'default') bytes [source]¶
Return all data recieved until connection closes or the timeout elapses.
Aliases: read_all, readall, recvall
- recv_exactly(n: int, timeout: float | int | Literal['default'] | None = 'default') bytes [source]¶
Recieve exactly n bytes
Aliases: read_exactly, readexactly, recvexactly, recv_exact, read_exact, readexact, recvexact
- recv_until(s: bytes | str, max_size: int | None = None, timeout: float | int | Literal['default'] | None = 'default') bytes [source]¶
Recieve data from the socket until the given substring is observed. Data in the same datagram as the substring, following the substring, will not be returned and will be cached for future receives.
Aliases: read_until, readuntil, recvuntil
- send(s: bytes | str) int [source]¶
Sends all the given data to the socket.
Aliases: write, put, sendall, send_all
- send_line(line: bytes | str, ending: bytes | str | None = None) int [source]¶
Write the string to the wire, followed by a newline. The newline string can be changed by specifying the
ending
param or changingnc.LINE_ENDING
.Aliases: sendline, writeline, write_line, writeln, sendln
- settimeout(timeout) None [source]¶
Set the default timeout in seconds to use for subsequent socket operations. Set to None to wait forever, or 0 to be effectively nonblocking.
- shutdown(how=2) None [source]¶
Send a shutdown signal for one or both of reading and writing. Valid arguments are
socket.SHUT_RDWR
,socket.SHUT_RD
, andsocket.SHUT_WR
.Shutdown differs from closing in that it explicitly changes the state of the socket resource to closed, whereas closing will only decrement the number of peers on this end of the socket, since sockets can be a resource shared by multiple peers on a single OS. When the number of peers reaches zero, the socket is closed, but not deallocated, so you still need to call close. (except that this is python and close is automatically called on the deletion of the socket)
http://stackoverflow.com/questions/409783/socket-shutdown-vs-socket-close
- nclib.select.select(select_read: Iterable[Netcat], select_write: Iterable[Netcat] | None = None, select_exc: Iterable[Netcat] | None = None, timeout: None | int | float = None) Tuple[List[Netcat], List[Netcat], List[Netcat]] [source]¶
A select function which works for any netcat or simplesock object. This function is a drop-in replacement for python’s
select.select
.The main advantage is that sockets with multiple backing file descriptors are handled cleanly.
- nclib.netcat.merge(children, **kwargs) Netcat [source]¶
Return a Netcat object whose receives will be the merged stream of all the given children sockets.
- Parameters:
children – A list of socks of any kind to receive from
kwargs – Any additional keyword arguments will be passed on to the Netcat constructor. Notably, you might want to specify sock_send, since by default you will not be able to send data to a merged socket.
- nclib.netcat.ferry(left, right, ferry_left=True, ferry_right=True, suppress_timeout=True, suppress_raise_eof=False) None [source]¶
Establish a linkage between two socks, automatically copying any data that becomes available between the two.
- Parameters:
left – A netcat sock
right – Another netcat sock
ferry_left – Whether to copy data leftward, i.e. from the right sock to the left sock
ferry_right – Whether to copy data rightward, i.e. from the left sock to the right sock
suppress_timeout – Whether to automatically set the socks’ timeout property to None and then reset it at the end
suppress_raise_eof – Whether to automatically set the socks’ raise_eof property to None and then reset it at the end