I am trying to build a HTTP server in python,
that sniffs packets and sends them to an other interface.
the server can get routing paths through a POST http request.
So that I need that the server will parallely sniff pakets and listen to http requests.
this is my code:
from scapy.all import *
from scapy.layers.inet import IP, UDP
from http.server import BaseHTTPRequestHandler, HTTPServer
import json
from socketserver import ThreadingMixIn
import threading
ROUTING_LIST = []
INTERFACE_TO_SNIFF = 'vEthernet'
PORT = 80
class Route:
def __init__(self):
self.first_IP_src = ""
self.first_port_src = ""
self.first_IP_dst = ""
self.first_port_dst = ""
self.first_iface = ""
self.second_IP_src = ""
self.second_port_src = ""
self.second_IP_dst = ""
self.second_port_dst = ""
self.second_iface = ""
class Server(BaseHTTPRequestHandler):
# POST echoes the message adding a JSON field
def do_POST(self):
# read the message and convert it into a python dictionary
length = int(self.headers['Content-length'])
message = self.rfile.read(length)
routing_dict = json.loads(message, strict=False)
if add_routing_http(routing_dict) is True:
print("New Routing received:")
print("{" + "\n".join("{!r}: {!r},".format(k, v) for k, v in routing_dict.items()) + "}")
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(
("POST routing request received! now we have " + str(len(ROUTING_LIST)) + " routes").encode("utf8"))
def run_server():
global PORT
server_address = ('', PORT)
httpd = HTTPServer(server_address, Server)
print('Starting httpd on port %d...' % PORT)
httpd.serve_forever()
def add_routing_local(first_IP_src, first_port_src, first_IP_dst, first_port_dst, first_iface,
second_IP_src, second_port_src, second_IP_dst, second_port_dst, second_iface):
global ROUTING_LIST
temp = Route()
temp.first_IP_src = first_IP_src
temp.first_port_src = first_port_src
temp.first_IP_dst = first_IP_dst
temp.first_port_dst = first_port_dst
temp.first_iface = first_iface
temp.second_IP_src = second_IP_src
temp.second_port_src = second_port_src
temp.second_IP_dst = second_IP_dst
temp.second_port_dst = second_port_dst
temp.second_iface = second_iface
ROUTING_LIST.append(temp)
def add_routing_http(routing_dict):
global ROUTING_LIST
temp = Route()
temp.first_IP_src = routing_dict.get('firstIpSrc')
temp.first_port_src = routing_dict.get('firstPortSrc')
temp.first_IP_dst = routing_dict.get('firstIpDst')
temp.first_port_dst = routing_dict.get('firstPortDst')
temp.first_iface = routing_dict.get('firstIface')
temp.second_IP_src = routing_dict.get('secondIpSrc')
temp.second_port_src = routing_dict.get('secondPortSrc')
temp.second_IP_dst = routing_dict.get('secondIpDst')
temp.second_port_dst = routing_dict.get('secondPortDst')
temp.second_iface = routing_dict.get('secondIface')
ROUTING_LIST.append(temp)
return True
def packets_filter(packet):
return IP in packet and UDP in packet and Raw in packet
def match_packet(packet, routing):
match = True
if routing.first_IP_src != '' and packet[IP].src != routing.first_IP_src:
return False
if routing.first_IP_dst != '' and packet[IP].dst != routing.first_IP_dst:
return False
if routing.first_port_src != '' and packet[UDP].sport != routing.first_port_src:
return False
if routing.first_port_dst != '' and packet[UDP].dport != routing.first_port_dst:
return False
if routing.first_iface != '' and packet.sniffed_on is not None and routing.first_iface != packet.sniffed_on:
return False
return True
def handle_packet(packet):
global ROUTING_LIST
for routing in ROUTING_LIST:
if match_packet(packet, routing) is True:
new_packet = packet.copy()
new_packet[IP].src = routing.second_IP_src
new_packet[IP].dst = routing.second_IP_dst
new_packet[UDP].sport = routing.second_port_src
new_packet[UDP].dport = routing.second_port_dst
new_packet.show()
sendp(new_packet) # sendp(new_packet, iface=routing.second_iface)iface='eth0'
return
def main():
daemon = threading.Thread(name='daemon_server', target=run_server, args=())
daemon.setDaemon(True) # Set as a daemon so it will be killed once the main thread is dead.
daemon.start()
print("start sniffing")
sniff(lfilter=packets_filter, prn=handle_packet) # sniff(lfilter=packets_filter, prn=handle_packet, iface=INTERFACE_TO_SNIFF)
if __name__ == "__main__":
main()
In short - I wantthe main function to run in parallel both of functions: run_server, sniff. if I try to run inly one of them - both work great.
In this code only the run_server works but not the sniffing.
What is wrong?
thank you
You have created Thread only for the run_server method. In order to run the sniff function on multithreaded, you will have to create a thread for the sniff function too.
You can learn about basic multithreading from this document:
https://www.geeksforgeeks.org/multithreading-python-set-1/
I am using https://github.com/brendano/stanford_corenlp_pywrapper. It has a sock.py script for communcation which works for python2.
from __future__ import division
import subprocess, tempfile, time, os, logging, re, struct, socket, atexit, glob, itertools
from copy import copy,deepcopy
from pprint import pprint
try:
import ujson as json
except ImportError:
import json
# SUGGESTED: for constituent parsing models, specify shift-reduce parser in
# configdict with:
# 'parse.model': 'edu/stanford/nlp/models/srparser/englishSR.ser.gz'
MODES_items = [
('ssplit', {'annotators': "tokenize, ssplit",
'description': "tokenization and sentence splitting (included in all subsequent ones)", }),
('pos', {'annotators':"tokenize, ssplit, pos, lemma",
'description':"POS (and lemmas)",}),
('ner', {'annotators':"tokenize, ssplit, pos, lemma, ner, entitymentions",
'description':"POS and NER (and lemmas)",}),
('parse', {'annotators':"tokenize, ssplit, pos, lemma, parse",
'description':"fairly basic parsing with POS, lemmas, trees, dependencies",}),
('nerparse', {'annotators':"tokenize, ssplit, pos, lemma, ner, entitymentions, parse",
'description':"parsing with NER, POS, lemmas, depenencies."}),
('coref', {'annotators':"tokenize, ssplit, pos, lemma, ner, entitymentions, parse, dcoref",
'description':"Coreference, including constituent parsing."})
]
MODES = dict(MODES_items)
logging.basicConfig() # wtf, why we have to call this?
LOG = logging.getLogger("CoreNLP_PyWrapper")
LOG.setLevel("INFO")
# LOG.setLevel("DEBUG")
PARSEDOC_TIMEOUT_SEC = 60 * 5
STARTUP_BUSY_WAIT_INTERVAL_SEC = 1.0
def command(mode=None, configfile=None, configdict=None, comm_mode=None,
java_command="java",
java_options="-Xmx4g -XX:ParallelGCThreads=1",
**kwargs):
d = {}
d.update(**locals())
d.update(**kwargs)
more_config = ""
if mode is None and configfile is None and configdict is None:
assert False, "Need to set mode, or the annotators directly, for this wrapper to work."
if mode:
if configdict is not None:
assert 'annotators' not in configdict, "mode was given but annotators are set in the configdict. use only one please."
elif configdict is None:
configdict = {}
LOG.info("mode given as '%s' so setting annotators: %s" % (mode, MODES[mode]['annotators']))
configdict['annotators'] = MODES[mode]['annotators']
if configfile:
more_config += " --configfile {}".format(configfile)
if configdict:
j = json.dumps(configdict)
assert "'" not in j, "can't handle single quote in config values"
more_config += " --configdict '{}'".format(j)
d['more_config'] = more_config
if comm_mode=='SOCKET':
d['comm_info'] = "--server {server_port}".format(**d)
elif comm_mode=='PIPE':
d['comm_info'] = "--outpipe {outpipe}".format(**d)
else: assert False, "need comm_mode to be SOCKET or PIPE but got " + repr(comm_mode)
cmd = """exec {java_command} {java_options} -cp '{classpath}'
corenlp.SocketServer {comm_info} {more_config}"""
return cmd.format(**d).replace("\n", " ")
class SubprocessCrashed(Exception):
pass
class CoreNLP:
def __init__(self, mode=None,
configfile=None, configdict=None,
corenlp_jars=(
"/home/sw/corenlp/stanford-corenlp-full-2015-04-20/*",
"/home/sw/stanford-srparser-2014-10-23-models.jar",
),
comm_mode='PIPE', # SOCKET or PIPE
server_port=12340, outpipe_filename_prefix="/tmp/corenlp_pywrap_pipe",
**more_configdict_args
):
self.mode = mode
self.proc = None
self.server_port = server_port
self.configfile = configfile
self.comm_mode = comm_mode
self.outpipe = None
self.configdict = deepcopy(configdict)
if not self.configdict: self.configdict = {}
self.configdict.update(more_configdict_args)
if not self.configdict: self.configdict = None
if self.comm_mode=='PIPE':
tag = "pypid=%d_time=%s" % (os.getpid(), time.time())
self.outpipe = "%s_%s" % (outpipe_filename_prefix, tag)
assert not os.path.exists(self.outpipe)
assert isinstance(corenlp_jars, (list,tuple))
deglobbed = itertools.chain(*[glob.glob(f) for f in corenlp_jars])
assert any(os.path.exists(f) for f in deglobbed), "CoreNLP jar files don't seem to exist; are the paths correct? Searched files: %s" % repr(deglobbed)
local_libdir = os.path.join(os.path.abspath(os.path.dirname(__file__)),
'lib')
jars = [os.path.join(local_libdir, "*")]
jars += corenlp_jars
self.classpath = ':'.join(jars)
# self.classpath += ":../bin:bin" ## for eclipse java dev
# LOG.info("CLASSPATH: " + self.classpath)
self.start_server()
# This probably is only half-reliable, but worth a shot.
atexit.register(self.cleanup)
def cleanup(self):
self.kill_proc_if_running()
if self.outpipe and os.path.exists(self.outpipe):
os.unlink(self.outpipe)
def __del__(self):
# This is also an unreliable way to ensure the subproc is gone, but
# might as well try
self.cleanup()
def start_server(self):
self.kill_proc_if_running()
if self.comm_mode=='PIPE':
if not os.path.exists(self.outpipe):
os.mkfifo(self.outpipe)
cmd = command(**self.__dict__)
LOG.info("Starting java subprocess, and waiting for signal it's ready, with command: %s" % cmd)
self.proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE)
time.sleep(STARTUP_BUSY_WAIT_INTERVAL_SEC)
if self.comm_mode=='SOCKET':
sock = self.get_socket(num_retries=100, retry_interval=STARTUP_BUSY_WAIT_INTERVAL_SEC)
sock.close()
elif self.comm_mode=='PIPE':
self.outpipe_fp = open(self.outpipe, 'r')
while True:
# This loop is for if you have timeouts for the socket connection
# The pipe system doesn't have timeouts, so this should run only
# once in that case.
try:
ret = self.send_command_and_parse_result('PING\t""', 2)
if ret is None:
continue
assert ret == "PONG", "Bad return data on startup ping: " + ret
LOG.info("Successful ping. The server has started.")
break
except socket.error, e:
LOG.info("Waiting for startup: ping got exception: %s %s" % (type(e), e))
LOG.info("pausing before retry")
time.sleep(STARTUP_BUSY_WAIT_INTERVAL_SEC)
LOG.info("Subprocess is ready.")
def ensure_proc_is_running(self):
if self.proc is None:
# Has never been started
self.start_server()
elif self.proc.poll() is not None:
# Restart
self.start_server()
def kill_proc_if_running(self):
if self.proc is None:
# it's never been started yet
return
retcode = self.proc.poll()
if retcode is not None:
LOG.info("Subprocess seems to be stopped, exit code %s" % retcode)
elif retcode is None:
LOG.warning("Killing subprocess %s" % self.proc.pid)
os.kill(self.proc.pid, 9)
def parse_doc(self, text, timeout=PARSEDOC_TIMEOUT_SEC, raw=False):
cmd = "PARSEDOC\t%s" % json.dumps(text)
return self.send_command_and_parse_result(cmd, timeout, raw=raw)
def get_socket(self, num_retries=1, retry_interval=1):
# could be smarter here about reusing the same socket?
for trial in range(num_retries):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # not sure if this is needed?
sock.connect(('localhost', self.server_port))
return sock
except (socket.error, socket.timeout) as e:
LOG.info("socket error when making connection (%s)" % e)
if trial < num_retries-1:
LOG.info("pausing before retry")
time.sleep(retry_interval)
assert False, "couldnt connect socket"
def send_command_and_parse_result(self, cmd, timeout, raw=False):
try:
self.ensure_proc_is_running()
data = self.send_command_and_get_string_result(cmd, timeout)
if data is None: return None
decoded = None
if raw:
return data
try:
decoded = json.loads(data)
except ValueError:
LOG.warning("Bad JSON returned from subprocess; returning null.")
LOG.warning("Bad JSON length %d, starts with: %s" % (len(data), repr(data[:1000])))
return None
return decoded
except socket.timeout, e:
LOG.info("Socket timeout happened, returning None: %s %s" % (type(e), e))
return None
# This is tricky. maybe the process is running smoothly but just
# taking longer than we like. if it's in thie state, and we try to
# send another command, what happens? Should we forcibly restart
# the process now just in case?
def send_command_and_get_string_result(self, cmd, timeout):
if self.comm_mode == 'SOCKET':
sock = self.get_socket(num_retries=100)
sock.settimeout(timeout)
sock.sendall(cmd + "\n")
size_info_str = sock.recv(8)
elif self.comm_mode == 'PIPE':
self.proc.stdin.write(cmd + "\n")
self.proc.stdin.flush()
size_info_str = self.outpipe_fp.read(8)
# java "long" is 8 bytes, which python struct calls "long long".
# java default byte ordering is big-endian.
size_info = struct.unpack('>Q', size_info_str)[0]
# print "size expected", size_info
chunks = []
curlen = lambda: sum(len(x) for x in chunks)
while True:
remaining_size = size_info - curlen()
if self.comm_mode == 'SOCKET':
data = sock.recv(remaining_size)
elif self.comm_mode == 'PIPE':
data = self.outpipe_fp.read(remaining_size)
chunks.append(data)
if curlen() >= size_info: break
if len(chunks) > 1000:
LOG.warning("Incomplete value from server")
return None
time.sleep(0.01)
return ''.join(chunks)
def test_modes():
import pytest
gosimple(comm_mode='SOCKET')
gosimple(comm_mode='PIPE')
with pytest.raises(AssertionError):
gosimple(comm_mode=None)
with pytest.raises(AssertionError):
gosimple(comm_mode='asdfasdf')
def test_coref():
assert_no_java("no java when starting")
p = CoreNLP("coref")
ret = p.parse_doc("I saw Fred. He saw me.")
pprint(ret)
assert 'entities' in ret
assert isinstance(ret['entities'], list)
def gosimple(**kwargs):
assert_no_java("no java when starting")
p = CoreNLP("ssplit", **kwargs)
ret = p.parse_doc("Hello world.")
# pprint(ret)
assert len(ret['sentences']) == 1
assert u' '.join(ret['sentences'][0]['tokens']) == u"Hello world ."
p.kill_proc_if_running()
assert_no_java()
def test_paths():
import pytest
with pytest.raises(AssertionError):
CoreNLP("ssplit", corenlp_jars=["/asdfadsf/asdfasdf"])
def assert_no_java(msg=""):
ps_output = os.popen("ps wux").readlines()
javalines = [x for x in ps_output if re.search(r'\bbin/java\b', x)]
print ''.join(javalines)
assert len(javalines) == 0, msg
# def test_doctimeout():
# assert_no_java("no java when starting")
#
# p = CoreNLP("pos")
# ret = p.parse_doc(open("allbrown.txt").read(), 0.5)
# assert ret is None
# p.kill_proc_if_running()
# assert_no_java()
if __name__=='__main__':
import sys
if sys.argv[1]=='modes':
for mode,d in MODES_items:
print " * `%s`: %s" % (mode, d['description'])
if sys.argv[1]=='modes_json':
# import json as stdjson
# print stdjson.dumps(MODES, indent=4)
print '"%s"' % json.dumps(MODES).replace('"', r'\"')
I changed it to python3 using 2to3 script which addded brackets around print and changed exception handling. Updated code
"""
Client and process monitor for the java socket server.
"""
import subprocess, tempfile, time, os, logging, re, struct, socket, atexit, glob, itertools
from copy import copy,deepcopy
from pprint import pprint
try:
import ujson as json
except ImportError:
import json
# SUGGESTED: for constituent parsing models, specify shift-reduce parser in
# configdict with:
# 'parse.model': 'edu/stanford/nlp/models/srparser/englishSR.ser.gz'
MODES_items = [
('ssplit', {'annotators': "tokenize, ssplit",
'description': "tokenization and sentence splitting (included in all subsequent ones)", }),
('pos', {'annotators':"tokenize, ssplit, pos, lemma",
'description':"POS (and lemmas)",}),
('ner', {'annotators':"tokenize, ssplit, pos, lemma, ner, entitymentions",
'description':"POS and NER (and lemmas)",}),
('parse', {'annotators':"tokenize, ssplit, pos, lemma, parse",
'description':"fairly basic parsing with POS, lemmas, trees, dependencies",}),
('nerparse', {'annotators':"tokenize, ssplit, pos, lemma, ner, entitymentions, parse",
'description':"parsing with NER, POS, lemmas, depenencies."}),
('coref', {'annotators':"tokenize, ssplit, pos, lemma, ner, entitymentions, parse, dcoref",
'description':"Coreference, including constituent parsing."})
]
MODES = dict(MODES_items)
logging.basicConfig() # wtf, why we have to call this?
LOG = logging.getLogger("CoreNLP_PyWrapper")
LOG.setLevel("INFO")
# LOG.setLevel("DEBUG")
PARSEDOC_TIMEOUT_SEC = 60 * 5
STARTUP_BUSY_WAIT_INTERVAL_SEC = 1.0
def command(mode=None, configfile=None, configdict=None, comm_mode=None,
java_command="java",
java_options="-Xmx4g -XX:ParallelGCThreads=1",
**kwargs):
d = {}
d.update(**locals())
d.update(**kwargs)
more_config = ""
if mode is None and configfile is None and configdict is None:
assert False, "Need to set mode, or the annotators directly, for this wrapper to work."
if mode:
if configdict is not None:
assert 'annotators' not in configdict, "mode was given but annotators are set in the configdict. use only one please."
elif configdict is None:
configdict = {}
LOG.info("mode given as '%s' so setting annotators: %s" % (mode, MODES[mode]['annotators']))
configdict['annotators'] = MODES[mode]['annotators']
if configfile:
more_config += " --configfile {}".format(configfile)
if configdict:
j = json.dumps(configdict)
assert "'" not in j, "can't handle single quote in config values"
more_config += " --configdict '{}'".format(j)
d['more_config'] = more_config
if comm_mode=='SOCKET':
d['comm_info'] = "--server {server_port}".format(**d)
elif comm_mode=='PIPE':
d['comm_info'] = "--outpipe {outpipe}".format(**d)
else: assert False, "need comm_mode to be SOCKET or PIPE but got " + repr(comm_mode)
cmd = """exec {java_command} {java_options} -cp '{classpath}'
corenlp.SocketServer {comm_info} {more_config}"""
return cmd.format(**d).replace("\n", " ")
class SubprocessCrashed(Exception):
pass
class CoreNLP:
def __init__(self, mode=None,
configfile=None, configdict=None,
corenlp_jars=(
"/home/sw/corenlp/stanford-corenlp-full-2015-04-20/*",
"/home/sw/stanford-srparser-2014-10-23-models.jar",
),
comm_mode='PIPE', # SOCKET or PIPE
server_port=12340, outpipe_filename_prefix="/tmp/corenlp_pywrap_pipe",
**more_configdict_args
):
self.mode = mode
self.proc = None
self.server_port = server_port
self.configfile = configfile
self.comm_mode = comm_mode
self.outpipe = None
self.configdict = deepcopy(configdict)
if not self.configdict: self.configdict = {}
self.configdict.update(more_configdict_args)
if not self.configdict: self.configdict = None
if self.comm_mode=='PIPE':
tag = "pypid=%d_time=%s" % (os.getpid(), time.time())
self.outpipe = "%s_%s" % (outpipe_filename_prefix, tag)
assert not os.path.exists(self.outpipe)
assert isinstance(corenlp_jars, (list,tuple))
deglobbed = itertools.chain(*[glob.glob(f) for f in corenlp_jars])
assert any(os.path.exists(f) for f in deglobbed), "CoreNLP jar files don't seem to exist; are the paths correct? Searched files: %s" % repr(deglobbed)
local_libdir = os.path.join(os.path.abspath(os.path.dirname(__file__)),
'lib')
jars = [os.path.join(local_libdir, "*")]
jars += corenlp_jars
self.classpath = ':'.join(jars)
# self.classpath += ":../bin:bin" ## for eclipse java dev
# LOG.info("CLASSPATH: " + self.classpath)
self.start_server()
# This probably is only half-reliable, but worth a shot.
atexit.register(self.cleanup)
def cleanup(self):
self.kill_proc_if_running()
if self.outpipe and os.path.exists(self.outpipe):
os.unlink(self.outpipe)
def __del__(self):
# This is also an unreliable way to ensure the subproc is gone, but
# might as well try
self.cleanup()
def start_server(self):
self.kill_proc_if_running()
if self.comm_mode=='PIPE':
if not os.path.exists(self.outpipe):
os.mkfifo(self.outpipe)
cmd = command(**self.__dict__)
LOG.info("Starting java subprocess, and waiting for signal it's ready, with command: %s" % cmd)
self.proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE)
time.sleep(STARTUP_BUSY_WAIT_INTERVAL_SEC)
if self.comm_mode=='SOCKET':
sock = self.get_socket(num_retries=100, retry_interval=STARTUP_BUSY_WAIT_INTERVAL_SEC)
sock.close()
elif self.comm_mode=='PIPE':
self.outpipe_fp = open(self.outpipe, 'r')
while True:
# This loop is for if you have timeouts for the socket connection
# The pipe system doesn't have timeouts, so this should run only
# once in that case.
try:
ret = self.send_command_and_parse_result('PING\t""', 2)
if ret is None:
continue
assert ret == "PONG", "Bad return data on startup ping: " + ret
LOG.info("Successful ping. The server has started.")
break
except socket.error as e:
LOG.info("Waiting for startup: ping got exception: %s %s" % (type(e), e))
LOG.info("pausing before retry")
time.sleep(STARTUP_BUSY_WAIT_INTERVAL_SEC)
LOG.info("Subprocess is ready.")
def ensure_proc_is_running(self):
if self.proc is None:
# Has never been started
self.start_server()
elif self.proc.poll() is not None:
# Restart
self.start_server()
def kill_proc_if_running(self):
if self.proc is None:
# it's never been started yet
return
retcode = self.proc.poll()
if retcode is not None:
LOG.info("Subprocess seems to be stopped, exit code %s" % retcode)
elif retcode is None:
LOG.warning("Killing subprocess %s" % self.proc.pid)
os.kill(self.proc.pid, 9)
def parse_doc(self, text, timeout=PARSEDOC_TIMEOUT_SEC, raw=False):
cmd = "PARSEDOC\t%s" % json.dumps(text)
return self.send_command_and_parse_result(cmd, timeout, raw=raw)
def get_socket(self, num_retries=1, retry_interval=1):
# could be smarter here about reusing the same socket?
for trial in range(num_retries):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # not sure if this is needed?
sock.connect(('localhost', self.server_port))
return sock
except (socket.error, socket.timeout) as e:
LOG.info("socket error when making connection (%s)" % e)
if trial < num_retries-1:
LOG.info("pausing before retry")
time.sleep(retry_interval)
assert False, "couldnt connect socket"
def send_command_and_parse_result(self, cmd, timeout, raw=False):
try:
self.ensure_proc_is_running()
data = self.send_command_and_get_string_result(cmd, timeout)
if data is None: return None
decoded = None
if raw:
return data
try:
decoded = json.loads(data)
except ValueError:
LOG.warning("Bad JSON returned from subprocess; returning null.")
LOG.warning("Bad JSON length %d, starts with: %s" % (len(data), repr(data[:1000])))
return None
return decoded
except socket.timeout as e:
LOG.info("Socket timeout happened, returning None: %s %s" % (type(e), e))
return None
# This is tricky. maybe the process is running smoothly but just
# taking longer than we like. if it's in thie state, and we try to
# send another command, what happens? Should we forcibly restart
# the process now just in case?
def send_command_and_get_string_result(self, cmd, timeout):
if self.comm_mode == 'SOCKET':
sock = self.get_socket(num_retries=100)
sock.settimeout(timeout)
sock.sendall(cmd + "\n")
size_info_str = sock.recv(8)
elif self.comm_mode == 'PIPE':
self.proc.stdin.write(cmd + "\n")
self.proc.stdin.flush()
size_info_str = self.outpipe_fp.read(8)
# java "long" is 8 bytes, which python struct calls "long long".
# java default byte ordering is big-endian.
size_info = struct.unpack('>Q', size_info_str)[0]
# print "size expected", size_info
chunks = []
curlen = lambda: sum(len(x) for x in chunks)
while True:
remaining_size = size_info - curlen()
if self.comm_mode == 'SOCKET':
data = sock.recv(remaining_size)
elif self.comm_mode == 'PIPE':
data = self.outpipe_fp.read(remaining_size)
chunks.append(data)
if curlen() >= size_info: break
if len(chunks) > 1000:
LOG.warning("Incomplete value from server")
return None
time.sleep(0.01)
return ''.join(chunks)
def test_modes():
import pytest
gosimple(comm_mode='SOCKET')
gosimple(comm_mode='PIPE')
with pytest.raises(AssertionError):
gosimple(comm_mode=None)
with pytest.raises(AssertionError):
gosimple(comm_mode='asdfasdf')
def test_coref():
assert_no_java("no java when starting")
p = CoreNLP("coref")
ret = p.parse_doc("I saw Fred. He saw me.")
pprint(ret)
assert 'entities' in ret
assert isinstance(ret['entities'], list)
def gosimple(**kwargs):
assert_no_java("no java when starting")
p = CoreNLP("ssplit", **kwargs)
ret = p.parse_doc("Hello world.")
# pprint(ret)
assert len(ret['sentences']) == 1
assert ' '.join(ret['sentences'][0]['tokens']) == "Hello world ."
p.kill_proc_if_running()
assert_no_java()
def test_paths():
import pytest
with pytest.raises(AssertionError):
CoreNLP("ssplit", corenlp_jars=["/asdfadsf/asdfasdf"])
def assert_no_java(msg=""):
ps_output = os.popen("ps wux").readlines()
javalines = [x for x in ps_output if re.search(r'\bbin/java\b', x)]
print(''.join(javalines))
assert len(javalines) == 0, msg
# def test_doctimeout():
# assert_no_java("no java when starting")
#
# p = CoreNLP("pos")
# ret = p.parse_doc(open("allbrown.txt").read(), 0.5)
# assert ret is None
# p.kill_proc_if_running()
# assert_no_java()
if __name__=='__main__':
import sys
if sys.argv[1]=='modes':
for mode,d in MODES_items:
print(" * `%s`: %s" % (mode, d['description']))
if sys.argv[1]=='modes_json':
# import json as stdjson
# print stdjson.dumps(MODES, indent=4)
print('"%s"' % json.dumps(MODES).replace('"', r'\"'))
However, I still get an error at
byteself.proc.stdin.write(cmd + "\n")
TypeError: a bytes-like object is required, not 'str'
I know it has to do with encoding and I may have to use encode/decode at a few places where it reads/writes but since I have not worked with sockets a lot, I am not sure where to change.
This question already has answers here:
Perform commands over ssh with Python
(17 answers)
Closed 6 years ago.
How can I use putty.exe with python to run remote unix commands like "mail" "cat" etc?
I have a file on my unix machine, I want to send that file content as an email
you dont
(or at least you shouldnt)
... instead use paramiko
here is a helper class I use with paramiko (see example use at the bottom) ... im pretty sure i found most of this class in some other stack overflow answer years ago
from contextlib import contextmanager
import os
import re
import paramiko
import time
class SshClient:
"""A wrapper of paramiko.SSHClient"""
TIMEOUT = 10
def __init__(self, connection_string,**kwargs):
self.key = kwargs.pop("key",None)
self.client = kwargs.pop("client",None)
self.connection_string = connection_string
try:
self.username,self.password,self.host = re.search("(\w+):(\w+)#(.*)",connection_string).groups()
except (TypeError,ValueError):
raise Exception("Invalid connection sting should be 'user:pass#ip'")
try:
self.host,self.port = self.host.split(":",1)
except (TypeError,ValueError):
self.port = "22"
self.connect(self.host,int(self.port),self.username,self.password,self.key)
def reconnect(self):
self.connect(self.host,int(self.port),self.username,self.password,self.key)
def connect(self, host, port, username, password, key=None):
self.client = paramiko.SSHClient()
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.client.connect(host, port, username=username, password=password, pkey=key, timeout=self.TIMEOUT)
def close(self):
if self.client is not None:
self.client.close()
self.client = None
def execute(self, command, sudo=False,**kwargs):
should_close=False
if not self.is_connected():
self.reconnect()
should_close = True
feed_password = False
if sudo and self.username != "root":
command = "sudo -S -p '' %s" % command
feed_password = self.password is not None and len(self.password) > 0
stdin, stdout, stderr = self.client.exec_command(command,**kwargs)
if feed_password:
stdin.write(self.password + "\n")
stdin.flush()
result = {'out': stdout.readlines(),
'err': stderr.readlines(),
'retval': stdout.channel.recv_exit_status()}
if should_close:
self.close()
return result
#contextmanager
def _get_sftp(self):
yield paramiko.SFTPClient.from_transport(self.client.get_transport())
def put_in_dir(self, src, dst):
if not isinstance(src,(list,tuple)):
src = [src]
print self.execute('''python -c "import os;os.makedirs('%s')"'''%dst)
with self._get_sftp() as sftp:
for s in src:
sftp.put(s, dst+os.path.basename(s))
def get(self, src, dst):
with self._get_sftp() as sftp:
sftp.get(src, dst)
def rm(self,*remote_paths):
for p in remote_paths:
self.execute("rm -rf {0}".format(p),sudo=True)
def mkdir(self,dirname):
print self.execute("mkdir {0}".format(dirname))
def remote_open(self,remote_file_path,open_mode):
with self._get_sftp() as sftp:
return sftp.open(remote_file_path,open_mode)
def is_connected(self):
transport = self.client.get_transport() if self.client else None
return transport and transport.is_active()
if __name__ == "__main__":
s = SshClient("user:password#192.168.1.125")
print s.execute("ls")
print s.execute("ls /etc",sudo=True)
The subprocess module is what you're looking for.
Here is a helpful tutorial on using it http://sharats.me/the-ever-useful-and-neat-subprocess-module.html
Beyond that, without specifics, we're not going to be much help to you.
I try to make two servers in a file, but they are fighting each other visibly
have anyone an idea to make them peace ?
here is my code :
# -*- coding: utf-8 -*-
import socket
import sys
import re
import base64
import binascii
import time
import zlib
import sys
import StringIO
import contextlib
import smtplib
from threading import Thread
"""
Thanks to :
People from irc :
Flox,Luyt
People from stack Overflow :
Philippe Leybaert,Platinum Azure,methodin,Suresh Kumar,S.Lott,MatTheCat,
kevpie,Ignacio Vazquez-Abrams,adamk,Frédéric Hamidi,THC4k,THC4k,Blam
"""
def sendmail(exp,dest,msg):
server = dest.split("#")[1]
s = smtplib.SMTP("localhost")
s.sendmail(exp,dest,msg)
#contextlib.contextmanager
def stdoutIO(stdout=None):
old = sys.stdout
if stdout is None:
stdout = StringIO.StringIO()
sys.stdout = stdout
yield stdout
sys.stdout = old
class Serversmtp(Thread):
def __init__self(self):
Thread.__init__(self)
def run(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('localhost', 25)
print >>sys.stderr, 'starting up on %s port %s' % server_address
self.sock.bind(server_address)
# Listen for incoming connections
self.sock.listen(1)
self.message = ""
while True:
# Wait for a connection
print >>sys.stderr, 'waiting for a connection'
connection, client_address = self.sock.accept()
try:
print >>sys.stderr, 'connection from', client_address
# Receive the data in small chunks and retransmit it
while True:
data = connection.recv(1024)
print >>sys.stderr, 'received "%s"' % data
if data:
self.message = self.traitement(data)
connection.sendall(self.message)
connection.close()
connection, client_address = self.sock.accept()
else:
print >>sys.stderr, 'no more data from', client_address
break
finally:
# Clean up the connection
connection.close()
self.sock.close()
class Pages :
def root(self,cgi=None):
return """eNqtVV1zqkgQfedX3MrrbNVREBnu5ubWCCoajPiRaHyTxEGNiAKC8uu3B7Nb+7JvO1QNNAOnT5/u
6Xnc5vHhSXsMk8/bk5bv7tdjmNK7XRz9yNKPXw+f63z9cxevow12H8mf4TrbtFt/CCE6QnRFl2Z1
H4hOoh57EU2OmsRETQPx9/p/D+3fhhXMLRhVrw07yC/ANPSuaOi6BTavihB2UZiwrW1D2sNNp8KL
lwhUNheFLaRwoQVeJtDotUXAa0AUlYUmMwzw0YlV6KVeievixiUPM8zhndMrOexaBWhYyPn5hKqn
C3BLi0oPQWvgojJtAmSbyMXE+BLEIOMFD5N8j65/NFDeTAIMcunDtXxycKnsgBdnJsFxVMCWZhf2
83ZqYPz+Tgz7PVFwvlWAA+GgaloiQINhj5d2OELpNCxw5yotOFlgoYyZXXBxvqSYpW6oESKDokxr
b6vuAdVsSAyt/cRFUDsYdzqSMznx6CMDsN0TB29lIwJMXUkOmi1ykF58aM/n4wL2MeOKLYG2xvsl
KtZ3JTe/SNRgUJIE+pAYs61ykHRJAsc6FSTEpRaOwV6WrGClZmz2OGTYgKWVjftgqNrQ9Xgm+XlP
jMbDEWXtMiHG5q70yUFE9q0nAjaezXwc31otWEOmvRUQX30LVp4GKjuQsNW9DT+FfkmmBc8VYDB8
V4BzJcFXqSTgZOvPZNtbiiA5fB01tKdvXsA2s2iPuBtNAS8xFLnCgjmutmj210MCPNAP49UHJeWy
pJBbtW0OyNYDIbmtGGvjAZVBe7voSfYxv7o4xbYDq73bBncNmYqbH9cFuPykH15WVJfVZkWMjJiy
HgwnHQr5lQBb2r6mnNGLtickk8udRDNtZxSqktDktBOMlEVgxk4vFLaBONz1cLs5KuQ4CjA+EWq1
WWhK1AM9j09dAmSkie1sqZCtjRfW2Sigc0pSvigTEvaVRDeXE5JgxMz7Oguz1REDT3xqhPimRDwo
D6bK2nroSJ6v5inc2+W5ri2gTnTjHJMEB3KI55WYo3iLHPDdZCHvjKlo98AtOl3B+/0PH93Z+opr
N8oL3uuOKgjhb1GKTlMSGlU+UJECJh8D/eXEx63/ToDTtSgw1vYHeRe5Hvbk1TbQEW5DAZDyrggM
AvQqsoUpyc7T728L2jpMD505AVJE3I5JM3QWVNmNM3PxnTy1taZfYYSyK5ikbkJsxMQzUY4EV91l
Q8UpXFm3jeDePS6Dl4lGGiwJcPROaS/6A2Lvx8Z3WTQ/5zrKZGSCABTD0mM1Y+VAhiqCjGyn9d2+
SDPqX8wPq4DFyxtV8mvZhd3PtlRYSlQLxKhKUCrAzyVE5LdVyATofEugK9ui7lF32oja8f8x/mnb
d8Bfvx6e7kfHb+2U7o75j4c8yZMH9qDePmi/nzTtEfej5hH1yfMXx7rT9A=="""
def favico(self):
return """eNqdk39MVWUYx99zDrZkJJc/dGtqsVZKFmttFhcuF0wXC1bTZmq0qVuWa8t+/NXPW1MQCk3FMBKs
LNauoq6AAr2zsFLLHAN1YQXJryzJewXuhV29HO759JyX//uj9933vOe8e7/f5/k+73OUMmR6PEqe
meq5FKXmKKWyBLIlO9P7/zUiEzaB02GWt43ycHOUx2St6YwTtxP0DZ6n+LV5LH5DURgwWRJQ5L+p
eEi+Xa4zZbP+aD9pByLMaR5jdkuUuV9NcNuhKIFTI4DD0bON3P+Kha/coLDMouAtRYHwl72u6IvE
mNvwG57QddJCUdJbY6S3jGmN+w5fYTwhCnackor55FZK3AqTfFmXbDbxSx4T9g1ygh2or0cxTzuk
nrSZ2R5HHbpKSVMvjuPAlMOq3XexuErh26HwC3/ZlhmShwFJOPfPON6mTlKb+lGtf2J+McSixov8
Hom6VAaGf6Ww8hZyq8X7exb+KpOCCvGwRXHueJDkSFj77B6bpOnSMLVdfVwdv4477KlJXggWs2iH
gbdG4otG7nbx8K5oicbO4jv4eJ2XlrdX8131i4z0dIlSUqZDOBbm+YNFZAs3v1a4NdPw7xJsE2xV
NJQu5PNV8/ik5Gb2PpJBdLhfe74cGeTx+gVk75F4H5r4BF55970vddtl4JccvFKPg6tn89FyD8GX
ltLesFX7tSXvn3tOcPurJg/sU+TUCeol3z2GhteNv92g4B2D/esWcrH9CI7UMREbpe/Ep1wb6tEe
6o5VcG+ZxKy3yNtrkSMecgV5u6UPxMdS4V8b7NW1i0eHad2UxfEnFKG1s7jcFdL7+5rryHx5Pjkf
SMxaS/t/sGom2c/mkX7PNvf6NC40lhFaqTj7TArfPmlyprpU58ANyLr7J2669QcyFjSTkdnGDI/0
izmIMrqF7PYHtAd8/LhWeBtNTj1l0rlzja6DO1asvESKmpDzYKmkrOPS+39hmT3Td2zbtG26kzMb
FF0bFd+XKi58We6mr3uvqGgAQyVQ1hSGkRCNMdEIi0a/2yDa57HyFYTWKDo2mHzz9Cxif/+h76L7
lzipaVfkbBLLcITnxo9LPhHxMKD/QeQfHOrtILg+k88eTeH8kUqxlGQ0miCv8KT2aZqTWsNU03yl
RjR3s6H+93C5/wIoQoi6"""
class Serverhttp(Thread):
def __init__(self):
Thread.__init__(self)
self.Pages = Pages()
self.GET = re.compile("GET.*?HTTP")
self.POST = re.compile("POST.*?HTTP")
self.balisep = re.compile("<\?.*\?>",re.DOTALL)
def run(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('localhost', 41000)
print >>sys.stderr, 'starting up on %s port %s' % server_address
self.sock.bind(server_address)
# Listen for incoming connections
self.sock.listen(1)
self.message = ""
while True:
# Wait for a connection
print >>sys.stderr, 'waiting for a connection'
connection, client_address = self.sock.accept()
try:
print >>sys.stderr, 'connection from', client_address
# Receive the data in small chunks and retransmit it
while True:
data = connection.recv(1024)
print >>sys.stderr, 'received "%s"' % data
if data:
self.message = self.traitement(data)
connection.sendall(self.message)
connection.close()
connection, client_address = self.sock.accept()
else:
print >>sys.stderr, 'no more data from', client_address
break
finally:
# Clean up the connection
connection.close()
self.sock.close()
def decompress_img(self,img):
img = zlib.decompress(base64.decodestring(img))
return img
def decompress_html(self,html) :
page = "HTTP/1.0 200 OK\r\nContent-type:text/html;charset=utf8\r\n\r\n"
page+=zlib.decompress(base64.decodestring(html))
commands = self.balisep.findall(page)
print commands
for c in commands :
command = c.replace("<? ","")
command = c.replace("<?","")
command = command.replace(" ?>","")
command = command.replace("?>","")
print command
with stdoutIO() as s:
exec(command)
page = page.replace(c,s.getvalue())
return page
def traitement(self,data):
url = self.POST.findall(data)
print url
print len(url)
url = self.GET.findall(data)
print url
url = url[0].replace("GET","")
url = url.replace("POST","")
url = url.replace("HTTP","")
url = url.replace(" ","")
print url
if url == "/favicon.ico":
return self.decompress_img(self.Pages.favico())
else :
return self.decompress_html(self.Pages.root())
if __name__ == "__main__":
swww = Serverhttp()
swww.start()
ssmtp = Serversmtp()
ssmtp.start()
sendmail("test#test.com","b#gmail.com","hello")
print "toto"
Regards and thanks all people
it was better to use : SocketServer.BaseRequestHandler with handler
and one for each server :
as seen here :
# MetaProject v 0.21
# -*- coding: utf-8 -*-
import socket
import sys
import re
import base64
import binascii
import time
import zlib
import sys
import StringIO
import contextlib
import smtplib
import threading
import SocketServer
SocketServer.TCPServer.allow_reuse_address = True
"""
Thanks to :
People from irc :
Flox,Luyt
People from stack Overflow (http://stackoverflow.com/):
Philippe Leybaert,Platinum Azure,methodin,Suresh Kumar,S.Lott,MatTheCat,
kevpie,Ignacio Vazquez-Abrams,adamk,Frédéric Hamidi,THC4k,THC4k,Blam,bstpierre
"""
def sendmail(exp,dest,msg):
server = dest.split("#")[1]
s = smtplib.SMTP("localhost")
s.sendmail(exp,dest,msg)
#contextlib.contextmanager
def stdoutIO(stdout=None):
old = sys.stdout
if stdout is None:
stdout = StringIO.StringIO()
sys.stdout = stdout
yield stdout
sys.stdout = old
class Serversmtp(SocketServer.BaseRequestHandler):
def handle(self):
self.data = self.request.recv(1024)
socket = self.request
print "%s wrote:" % self.client_address[0]
self.data = self.traitement(self.data)
socket.sendto(self.data, self.client_address)
def traitement(self,data):
return "toto"
class Pages :
def __init__(self):
self.balisep = re.compile("<\?.*\?>",re.DOTALL)
def root(self,cgi=None):
return self.decompress_html("""eNqzySjJzbHjsknKT6m04yrJhECbpCKgWGZuukJxUbKtUlpiWWZyfp4ekFCyg8jZcxUUZeaVKCiV
5JfkK2krgUSVuOztuLhs9CFm2eiDjQYAG5wecg==""")
def faviconico(self):
return self.decompress_img("""eNqdk39MVWUYx99zDrZkJJc/dGtqsVZKFmttFhcuF0wXC1bTZmq0qVuWa8t+/NXPW1MQCk3FMBKs
LNauoq6AAr2zsFLLHAN1YQXJryzJewXuhV29HO759JyX//uj9933vOe8e7/f5/k+73OUMmR6PEqe
meq5FKXmKKWyBLIlO9P7/zUiEzaB02GWt43ycHOUx2St6YwTtxP0DZ6n+LV5LH5DURgwWRJQ5L+p
eEi+Xa4zZbP+aD9pByLMaR5jdkuUuV9NcNuhKIFTI4DD0bON3P+Kha/coLDMouAtRYHwl72u6IvE
mNvwG57QddJCUdJbY6S3jGmN+w5fYTwhCnackor55FZK3AqTfFmXbDbxSx4T9g1ygh2or0cxTzuk
nrSZ2R5HHbpKSVMvjuPAlMOq3XexuErh26HwC3/ZlhmShwFJOPfPON6mTlKb+lGtf2J+McSixov8
Hom6VAaGf6Ww8hZyq8X7exb+KpOCCvGwRXHueJDkSFj77B6bpOnSMLVdfVwdv4477KlJXggWs2iH
gbdG4otG7nbx8K5oicbO4jv4eJ2XlrdX8131i4z0dIlSUqZDOBbm+YNFZAs3v1a4NdPw7xJsE2xV
NJQu5PNV8/ik5Gb2PpJBdLhfe74cGeTx+gVk75F4H5r4BF55970vddtl4JccvFKPg6tn89FyD8GX
ltLesFX7tSXvn3tOcPurJg/sU+TUCeol3z2GhteNv92g4B2D/esWcrH9CI7UMREbpe/Ep1wb6tEe
6o5VcG+ZxKy3yNtrkSMecgV5u6UPxMdS4V8b7NW1i0eHad2UxfEnFKG1s7jcFdL7+5rryHx5Pjkf
SMxaS/t/sGom2c/mkX7PNvf6NC40lhFaqTj7TArfPmlyprpU58ANyLr7J2669QcyFjSTkdnGDI/0
izmIMrqF7PYHtAd8/LhWeBtNTj1l0rlzja6DO1asvESKmpDzYKmkrOPS+39hmT3Td2zbtG26kzMb
FF0bFd+XKi58We6mr3uvqGgAQyVQ1hSGkRCNMdEIi0a/2yDa57HyFYTWKDo2mHzz9Cxif/+h76L7
lzipaVfkbBLLcITnxo9LPhHxMKD/QeQfHOrtILg+k88eTeH8kUqxlGQ0miCv8KT2aZqTWsNU03yl
RjR3s6H+93C5/wIoQoi6""")
def toto(self):
return self.decompress_html("""eNqzySjJzbHjsknKT6m04yrLLy1WSC1JLVZIVCjJL8nnstGHSNjog9UBAGolDzo=""")
def p404(self):
return self.decompress_html("""eNqzySjJzbHjsknKT6m04zIxMFFIScwrVihJVEhLTE5VUOSy0YdI2eiDVQIAZBgOeA==""")
def decompress_img(self,img):
img = zlib.decompress(base64.decodestring(img))
return img
def decompress_html(self,html) :
page = "HTTP/1.0 200 OK\r\nContent-type:text/html;charset=utf8\r\n\r\n"
page+=zlib.decompress(base64.decodestring(html))
commands = self.balisep.findall(page)
print commands
for c in commands :
command = c.replace("<? ","")
command = c.replace("<?","")
command = command.replace(" ?>","")
command = command.replace("?>","")
print command
with stdoutIO() as s:
exec(command)
page = page.replace(c,s.getvalue())
return page
class Serverhttp(SocketServer.BaseRequestHandler):
def handle(self):
self.Pages = Pages()
self.GET = re.compile("GET.*?HTTP")
self.POST = re.compile("POST.*?HTTP")
self.data = self.request.recv(1024)
socket = self.request
print "%s wrote:" % self.client_address[0]
self.data = self.traitement(self.data)
socket.sendto(self.data, self.client_address)
def traitement(self,data):
url = self.POST.findall(data)
url = self.GET.findall(data)
url = url[0].replace("GET","")
url = url.replace("POST","")
url = url.replace("HTTP","")
url = url.replace(" ","")
url = re.sub(r"^/","",url)
url = re.sub(r"\.","",url)
if url != "":
urls = url.split("/")
if len(urls) != 0 :
print urls
url = urls[0]
print "url %s"%url
if url == "" :
return self.Pages.root()
elif url in dir(self.Pages) and url != "":
return getattr(self.Pages,url)()
else :
return self.Pages.p404()
def serve_thread(host, port):
if port == 4242 :
server = SocketServer.TCPServer((host, port), Serverhttp,bind_and_activate=True)
elif port == 25 :
server = SocketServer.TCPServer((host, port), Serversmtp,bind_and_activate=True)
server.serve_forever()
if __name__ == "__main__":
threading.Thread(target=serve_thread,args=('localhost', 4242)).start()
threading.Thread(target=serve_thread,args=('localhost', 25)).start()
print "toto"