Skip to content

Instantly share code, notes, and snippets.

@milljm
Last active December 19, 2016 15:53
Show Gist options
  • Save milljm/efcee4fabd749848f192849b68e70e4a to your computer and use it in GitHub Desktop.
Save milljm/efcee4fabd749848f192849b68e70e4a to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
import argparse, os, io, sys, time
import SocketServer, socket
import Queue
import threading
import tempfile
global thread_storage
thread_storage = {}
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True,
queue=None):
self.queue = queue
SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass,
bind_and_activate=bind_and_activate)
class ThreadedTCPStreamHandler(SocketServer.StreamRequestHandler):
def __init__(self, request, client_address, server):
self.thread = threading.current_thread()
global thread_storage
thread_storage[self.thread] = server.queue
SocketServer.StreamRequestHandler.__init__(self, request, client_address, server)
def handle(self):
if self.thread.isAlive():
while True:
try:
read_data = ''
if self.thread in thread_storage.keys():
read_data = thread_storage[self.thread].get()
self.request.sendall(read_data)
except:
print 'client exited:', self.thread
break
def verifyArgs(args):
if args.remote_host:
if args.bind_host is None:
print 'Warning! binding to localhost by default. No one but folks on\nyour local machine will be able to connect to me. Use:\n\n\t--bind-host <ip>\n\nto bind to another device.'
args.bind_host = 'localhost'
return args
def parseArguments(args=None):
parser = argparse.ArgumentParser(description='Connect to TCP Stream, and become a server of said stream')
server = parser.add_argument_group('Server', 'Server Options')
server.add_argument('--remote-host', nargs='?', help='Connect to source host')
server.add_argument('--remote-port', nargs='?', help='Connect to source host using specified port')
server.add_argument('--bind-host', nargs='?', help='Attempt to bind to specified address (defaults to localhost)')
server.add_argument('--serve-port', nargs='?', help='Serve data stream on specified port')
client = parser.add_argument_group('Client Options')
client.add_argument('--server-host', nargs='?', help='Remote server host')
client.add_argument('--server-port', nargs='?', help='Remote server port')
client.add_argument('--write-file', nargs='?', help='Write to specified file instead to stdout')
return verifyArgs(parser.parse_args(args))
def createThreadStorage(buffer_data):
global thread_storage
for thread in threading.enumerate():
if thread in thread_storage.keys():
if not thread.isDaemon():
thread_storage[thread].put(buffer_data)
if __name__ == '__main__':
args = parseArguments()
try:
if args.remote_host:
server = ThreadedTCPServer((str(args.bind_host), int(args.serve_port)), ThreadedTCPStreamHandler, queue=Queue.Queue())
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()
remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote.connect((str(args.remote_host), int(args.remote_port)))
buffer_holder = ''
while True:
while len(buffer_holder) < 4096:
buffer_holder += remote.recv(4096 - len(buffer_holder))
createThreadStorage(buffer_holder)
buffer_holder = ''
elif args.server_host:
sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.connect((str(args.server_host), int(args.server_port)))
buffer_holder = ''
if args.write_file:
output = open(args.write_file, 'a')
while True:
while len(buffer_holder) < 4096:
buffer_holder += sk.recv(4096 - len(buffer_holder))
if args.write_file:
output.write(buffer_holder)
else:
sys.stdout.write(buffer_holder)
buffer_holder = ''
except socket.error:
print 'Socket Error'
sys.exit(1)
except KeyboardInterrupt:
if args.remote_host:
print 'Exiting...'
server.shutdown()
server.server_close()
else:
print 'Exiting'
sk.close()
sys.exit(0)
@milljm
Copy link
Author

milljm commented Dec 16, 2016

Little script that allows one to connect to a socket, and become a server of that socket (receive only).

Example...

Stream Server (some source of a stream):

netcat -l -p 5000 < /dev/random

Your server:

multi_connection_stream.py --remote-host <stream source hostname|ip> --remote-port 5000 --serve-port 8000

Your clients:

client 1:

multi_connection_stream.py --server-host <your server ip> --remote-port 8000 | aplay (or some other binary)

client 2:

multi_connection_stream.py --server-host <your server ip> --remote-port 8000 | aplay (or some other binary)

etc...

@milljm
Copy link
Author

milljm commented Dec 19, 2016

Don't use this script. I apparently wasn't "interneting" enough. I found the de facto standard tool one is supposed to use for this sort of thing: ncat, which is part of the nmap tool set.

I'll leave this script up as a reminder of my ignorance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment