Skip to content

Instantly share code, notes, and snippets.

@matthayter
Created March 27, 2020 17:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthayter/9ea19a84b882c946e31fa85de2ed2ac7 to your computer and use it in GitHub Desktop.
Save matthayter/9ea19a84b882c946e31fa85de2ed2ac7 to your computer and use it in GitHub Desktop.
Eventually planned to be a decent netcat replacement for windows.
import asyncio
import sys
import socket
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
from argparse import ArgumentParser
def parse_cl():
parser = ArgumentParser(description='Python netcat')
parser.add_argument('-l', '--listen', action='store_true',
help='Listen')
parser.add_argument('host',
help='Host')
parser.add_argument('port', type=int,
help='Port number')
return parser
server = None
async def connection_handler(reader, writer):
await connectionLoop(reader, writer)
server.close()
async def create_client(host, port):
reader, writer = await asyncio.open_connection(
host, port, family=socket.AF_INET6)
await connectionLoop(reader, writer)
async def listen_server(port):
global server
server = await asyncio.start_server(
connection_handler, None, port, family=socket.AF_INET6)
addr = server.sockets[0].getsockname()
print(f'Serving on {addr}')
async with server:
await server.wait_closed()
print("Server closed")
async def connectionLoop(reader, writer):
write_task = asyncio.create_task(pushLoop(writer))
await pullLoop(reader)
# Cancel writing, connection is closing.
write_task.cancel()
writer.close()
print("Connection cleaned up.")
def get_line_from_stdin():
return sys.stdin.readline()
async def asyncReadline():
return await asyncio.get_running_loop().run_in_executor(None, get_line_from_stdin)
async def pushLoop(writer):
while True:
line = await asyncReadline()
if line == '' or line == None:
break
print("writing line: ", line)
writer.write(line.encode())
await writer.drain()
print("Finished writing.")
writer.close()
async def pullLoop(reader):
while True:
line = await reader.readline()
if len(line) <= 0:
break
print("Got: ", line.decode())
print("Finished reading from remote.")
if __name__ == '__main__':
parser = parse_cl()
args = parser.parse_args()
if args.listen:
asyncio.run(listen_server(args.port))
else:
asyncio.run(create_client(args.host, args.port))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment