i have am problem with a Python Script here.
My Problem is, it works on a Raspberry 3 but it crashes under Ubuntu Server.
The Script connects via vpn to a Teltonika RUT955 LTE Router and collects GPS data. It works without problems. Now i copy the script from the raspberry to my Ubuntu Server (not a VM) and the script crash.
When i´m try the script on my Laptop (Linux Mint), it works. I have an other Ubuntu Server, but the same, it crashes.
My Python Version on my Raspi is 2.7.9, on my Ubuntu Server is 2.7.12
The Script crash at the function unpack.
And heres my code:
#!/usr/bin/env python
import socket
import threading
from time import gmtime, strftime
import ConfigParser
from optparse import OptionParser
import struct
import binascii
from datetime import datetime
import dbgps
import time
TCP_IP = '10.81.0.1'
TCP_PORT = 17050
def unpack(fmt, data):
try:
return struct.unpack(fmt, data)
except struct.error:
flen = struct.calcsize(fmt.replace('*', ''))
alen = len(data)
idx = fmt.find('*')
before_char = fmt[idx-1]
n = (alen-flen)/struct.calcsize(before_char)+1
fmt = ''.join((fmt[:idx-1], str(n), before_char, fmt[idx+1:]))
return struct.unpack(fmt, data)
class GPSTerminal:
def __init__(self, socket):
self.socket = socket[0]
self.ip = socket[1][0]
self.socket.settimeout(15)
self.initVariables()
def initVariables(self):
self.imei = "unknown"
self.sensorsDataBlocks = []
self.error = []
self.blockCount = 0
self.raw = ''
self.success = True
self.dataBreak = 0
self.possibleBreakCount = 5
def startReadData(self):
try:
self.proceedConnection()
except socket.timeout, e:
self.success = False
def proceedConnection(self):
if self.isCorrectConnection():
self.readIMEI()
if self.imei:
self.proceedData()
else:
self.error.append( "Incorrect connection data stream" )
self.success = False
def proceedData(self):
self.time = datetime.now()
self.data = self.readData()
if self.data:
Zeros, AVLLength, CodecID, BlockCount, Hexline = unpack("HLBBs*", self.data)
print "test"
self.Hexline = binascii.hexlify(Hexline)
self.blockCount = BlockCount
self.AVL = 0 # AVL ? Looks like data reading cursor
proceed = 0
AVLBlockPos = 0
while proceed < BlockCount:
try:
data = self.proceedBlockData()
if len(data) > 1: # Daten empfangen und in die DB schreiben
#dbgps.DBsendAlchemy("Update container_gps Set lon ='"+str(data['Lon'])+"', lat ='"+str(data['Lat'])+"', richtung='"+str(data['GpsCourse'])+"', Timestamp ='"+str(int(data['Timestamp']))+"' where IMEI='"+str(data['IMEI'])+"'")
#time.sleep(0.2)
print str(data['Lon'])
self.sensorsDataBlocks.append( data )
except ValueError, e:
self.dataBreak += 1
self.reReadData(Hexline)
if self.dataBreak > self.possibleBreakCount :
self.error.append( "Data break" )
self.success = False
return
else:
self.AVL = AVLBlockPos
proceed -= 1
proceed += 1
AVLBlockPos = self.AVL
else:
self.error.append( "No data received" )
self.success = False
def readData(self, length = 8192):
data = self.socket.recv(length)
self.raw += data
return data
def reReadData(self, Hexline):
HexlineNew = unpack("s*", self.readData())
Hexline += HexlineNew[0]
self.Hexline = binascii.hexlify(Hexline)
def proceedBlockData(self):
DateV = '0x'+ self.extract(16)
DateS = round(long( DateV, 16) /1000, 0)
Prio = self.extract_int(2)
GpsLon = self.extract_int(8)
GpsLat = self.extract_int(8)
Lon = str(float(GpsLon)/10000000)
Lat = str(float(GpsLat)/10000000)
GpsH = self.extract_int(4)
GpsCourse = self.extract_int(4)
GpsSat = self.extract_int(2)
GpsSpeed = self.extract_int(4)
IOEventCode = self.extract_int(2)
NumOfIO = self.extract_int(2)
sensorDataResult = {}
pais_count = 0
for i in [1,2,4,8]:
pc = 0
data = self.readSensorDataBytes(i)
for iocode in data.keys():
pais_count+=1
sensorDataResult[iocode] = data[iocode]
pc += 1
#return {'imei' : self.imei, 'date': DateS, 'Lon': Lon, 'Lat': Lat, 'GpsSpeed': GpsSpeed, 'GpsCourse': GpsCourse, 'sensorData': sensorDataResult}
return {'IMEI' : self.imei, 'Timestamp': DateS, 'Lon': Lon, 'Lat': Lat, 'GpsSpeed': GpsSpeed, 'GpsCourse': GpsCourse}
def readSensorDataBytes(self, count):
result = {}
pairsCount = self.extract_int(2)
i = 1
while i <= pairsCount:
IOCode = self.extract_int(2)
IOVal = self.extract_int( count * 2)
result[IOCode] = IOVal
i+=1
return result
def extract(self, length):
result = self.Hexline[ self.AVL : (self.AVL + length) ]
self.AVL += length
return result
def extract_int(self, length):
return int(self.extract(length), 16)
def readIMEI(self):
IMEI = self.readData(34)
self.imei = IMEI
self.socket.send(chr(01))
def isCorrectConnection(self):
hello = self.readData(2)
return '(15,)' == str(struct.unpack("!H", hello ))
def sendOKClient(self):
self.socket.send(struct.pack("!L", self.blockCount))
self.closeConnection()
def sendFalse(self):
self.socket.send(struct.pack("!L", 0))
self.closeConnection()
def closeConnection(self):
self.socket.close()
def getSensorData(self):
return self.sensorsDataBlocks
def getIp(self):
return self.ip
def getImei(self):
return self.imei
def isSuccess(self):
return self.success
class ClientThread(threading.Thread):
def __init__(self, group=None, target=None, name=None, *args, **kwargs):
threading.Thread.__init__(self)
self.socket = kwargs['socket']
def run(self):
client = self.socket
if client:
print "a"
terminalClient = GPSTerminal(self.socket)
print "b"
terminalClient.startReadData()
print "c"
if terminalClient.isSuccess():
terminalClient.sendOKClient()
else:
terminalClient.sendFalse()
pass
terminalClient.closeConnection()
if __name__ == "__main__":
optParser = OptionParser()
(options, args) = optParser.parse_args()
config = ConfigParser.RawConfigParser()
print "Server gestartet"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((TCP_IP, TCP_PORT))
server.listen(5)
while True:
ClientThread(socket=server.accept(), config = config).start()
Related
I have one rtsp server with multiple videos hosted using multiprocessing queues as channels using sensor factory objects using gstreamer. The reason for using multi processing queue is because of the limitation of nvh264enc encoder in the pipeline(The teardown causes the ports to be nonusable in subsequent client connections, no problem in x264enc). The problem happens when multiple clients are connected to the same link, even though the factory is shared between clients with same media element. This problem occurs. The results can be seen in clients such as vlc player.
"""
This module will provide encoder functionality
"""
from base64 import decode
from gc import get_stats
from os import stat
from queue import Empty
import sys
import itertools
import numpy as np
import logging
import threading
import multiprocessing as mp
import gi
from pprint import pprint
gi.require_version('Gst', '1.0')
gi.require_version('GstRtspServer', '1.0')
from gi.repository import Gst, GstRtspServer, GObject, GLib
import cv2
import subprocess
import time
GObject.threads_init()
Gst.init(None)
# def on_debug(category, level, dfile, dfctn, dline, source, message, user_data):
# if source:
# print('Debug {} {}: {}'.format(
# Gst.DebugLevel.get_name(level), source.name, message.get()))
# else:
# print('Debug {}: {}'.format(
# Gst.DebugLevel.get_name(level), message.get()))
# if not Gst.debug_is_active():
# Gst.debug_set_active(True)
# level = Gst.debug_get_default_threshold()
# Gst.debug_set_default_threshold(Gst.DebugLevel.INFO)
# if level < Gst.DebugLevel.ERROR:
# Gst.debug_set_default_threshold(Gst.DebugLevel.WARNING)
# Gst.debug_add_log_function(on_debug, None)
# Gst.debug_remove_log_function(Gst.debug_log_default)
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s:%(levelname)s:%(name)s:%(message)s',
handlers=[logging.FileHandler('GPU_enabled_frame_encode.log'), logging.StreamHandler(sys.stdout)])
logging.debug('Debug message')
logging.info('Info message')
logging.warning('Warning message')
logging.error('Error message')
logging.critical('Critical message')
class SensorFactory(GstRtspServer.RTSPMediaFactory):
def __init__(self, fps, img_shape, cols, verbosity=1, cap=None, speed_preset='medium', properties={}):
super(SensorFactory, self).__init__(**properties)
logging.info("sensory factory")
self.rtsp_media = None
self.height = int(img_shape[0])
self.width = int(img_shape[1] * cols)
self.number_frames = 0
self.stream_timestamp = 0.0
self.timestamp = time.time()
self.dt = 0.0
self.streamed_frames = 0
self.verbosity = verbosity
fps = int(fps)
self.cap = cap
self.appsrc = None
# duration of a frame in nanoseconds nvh264enc x264enc
self.duration = 1.0 / fps * Gst.SECOND
key_int_max = ' key-int-max={} '.format(fps)
caps_str = 'caps=video/x-raw,format=BGR,width={},height={},framerate={}/1 '.format(self.width,
self.height,
fps)
self.launch_string = 'appsrc name=source is-live=true block=true do-timestamp=true \
format=GST_FORMAT_TIME ' + caps_str + \
' ! queue' \
' ! videoconvert' \
' ! video/x-raw,format=I420' \
' ! nvh264enc' \
' ! rtph264pay config-interval=1 pt=96 name=pay0' \
''
def set_cap(self, cap):
self.cap = cap
def on_need_data(self, src, length):
# this method executes when client requests data
# logging.info("this method executes when client requests data")
# if self.cap.isOpened():
# _, frame = self.cap.get_frame()
# ret = True
if self.cap.isOpened():
frame_queue = self.cap.get_queue()
frame = frame_queue.get()
ret = True
if ret:
if frame.shape[:2] != (self.height, self.width):
frame = cv2.resize(frame, (self.width, self.height))
data = frame.tostring()
buf = Gst.Buffer.new_allocate(None, len(data), None)
buf.fill(0, data)
buf.duration = self.duration
timestamp = self.number_frames * self.duration
buf.pts = buf.dts = int(timestamp)
buf.offset = timestamp
self.number_frames += 1
retval = self.appsrc.emit('push-buffer', buf)
# print('pushed buffer, frame {}, duration {} ns, durations {} s'.format(self.number_frames,
# self.duration,
# self.duration / Gst.SECOND))
if retval != Gst.FlowReturn.OK:
logging.info("[INFO]: retval not OK: {}".format(retval))
if retval == Gst.FlowReturn.FLUSHING:
logging.info('Offline')
elif self.verbosity > 0:
logging.info("[INFO]: Unable to read frame from cap.")
# time.sleep(0.05)
def do_create_element(self, url):
if self.verbosity > 0:
request_uri = url.get_request_uri()
logging.info('[INFO]: stream request on {}'.format(request_uri))
return Gst.parse_launch(self.launch_string)
def do_configure(self, rtsp_media):
self.rtsp_media = rtsp_media
rtsp_media.set_reusable(True)
self.number_frames = 0
self.appsrc = rtsp_media.get_element().get_child_by_name('source')
# executes when client requests data
self.appsrc.connect('need-data', self.on_need_data)
def get_rtsp_media(self):
if self.rtsp_media:
return self.rtsp_media
def __del__(self):
print('Destructor called, factory deleted.')
class RTSP_utility_server(GstRtspServer.RTSPServer):
def __init__(self, fps, suffix='test', rtp_port=8554,
ip='12.0.0.0', caps=(None,), Sizes=[[1080, 1920]],
speed_preset='medium', verbosity=1, Indexes=[]):
GObject.threads_init()
Gst.init(None)
super(RTSP_utility_server, self).__init__(**{})
self.verbosity = verbosity
self.rtp_port = "{}".format(rtp_port)
if int(self.rtp_port) < 1024 and self.verbosity > 0:
logging.info(
'[INFO]: Note, admin privileges are required because port number < 1024.')
self.set_service(self.rtp_port)
self.speed_preset = speed_preset
self.caps = caps
self.factory = [None] * len(self.caps)
self.suffix = suffix
self.fps = fps
self.Sizes = Sizes
self.Indexes = Indexes
self.attach(None)
self.ip = self.get_ip()
self.media_path_list = [None] * len(self.caps)
self.clients_list = []
if len(self.suffix):
self.full_suffix = '/' + self.suffix.lstrip('/')
else:
self.full_suffix = ''
self.connect("client-connected", self.client_connected)
logging.info(
'[INFO]: streaming on:\n\trtsp://{}:{}/{}#'.format(self.ip, self.rtp_port, self.suffix))
self.status_thread = threading.Thread(target=self.status_thread_loop)
self.status_thread.daemon = True
self.status_thread.start()
self.context = GLib.MainContext()
print(self.attach(self.context))
def set_caps(self, caps):
if not isinstance(caps, (list, tuple)):
caps = [caps]
self.caps = caps
def create_media_factories(self):
mount_points = self.get_mount_points()
media_path_list = []
for i, cap in enumerate(self.caps):
img_shape = self.Sizes[i]
if len(self.Indexes) == 0:
N_Index = str(i + 1)
else:
N_Index = str(self.Indexes[i])
factory = SensorFactory(fps=self.fps, img_shape=img_shape, speed_preset=self.speed_preset,
cols=1, verbosity=self.verbosity, cap=cap)
factory.set_shared(True)
factory.set_stop_on_disconnect(True)
logging.info('inside media_factories Stream on ' +
self.full_suffix + N_Index)
logging.info('inside media_factories Stream on ' +
self.full_suffix + N_Index)
mount_points.add_factory(self.full_suffix + N_Index, factory)
self.factory[i] = factory
media_path_list.append(self.full_suffix + N_Index)
self.media_path_list = media_path_list
self.get_status()
def destroy_media_factories(self):
session_pool = self.get_session_pool()
logging.info("Number of sessions are :" +
str(session_pool.get_n_sessions()))
sessions_list = session_pool.filter()
for session in sessions_list:
for path in self.get_paths():
media_matched, _ = session.get_media(path)
if media_matched:
rtsp_media = media_matched.get_media()
rtsp_media.set_eos_shutdown(True)
rtsp_media.unprepare()
logging.debug("media removed for path "+path)
number_of_disconnects = session_pool.cleanup()
if number_of_disconnects > 0:
logging.info("number of disconnects:"+str(number_of_disconnects))
def destroy_media_factories_by_path(self,path_to_remove="/video1"):
session_pool = self.get_session_pool()
logging.info("Number of sessions are :" +
str(session_pool.get_n_sessions()))
sessions_list = session_pool.filter()
for session in sessions_list:
for path in self.get_paths():
media_matched, _ = session.get_media(path)
if media_matched and path==path_to_remove:
rtsp_media = media_matched.get_media()
rtsp_media.set_eos_shutdown(True)
rtsp_media.unprepare()
logging.debug("media removed for path "+path)
number_of_disconnects = session_pool.cleanup()
if number_of_disconnects > 0:
logging.info("number of disconnects:"+str(number_of_disconnects))
def client_connected(self, gst_server_obj, rtsp_client_obj):
logging.info('[INFO]: Client has connected')
self.create_media_factories()
self.clients_list.append(rtsp_client_obj)
if self.verbosity > 0:
logging.info('[INFO]: Client has connected')
def stop_all(self):
self.destroy_media_factories()
def stop_by_index(self,path):
self.destroy_media_factories_by_path(path)
def get_paths(self):
return self.media_path_list
def get_status(self):
mount_points = self.get_mount_points()
session_pool = self.get_session_pool()
# logging.info("Number of sessions are :" +
# str(session_pool.get_n_sessions()))
number_of_disconnects = session_pool.cleanup()
if number_of_disconnects > 0:
logging.info("number of disconnects:"+str(number_of_disconnects))
for path in self.get_paths():
sessions_list = session_pool.filter()
for session in sessions_list:
session.set_timeout(1)
media_matched, _ = session.get_media(path)
if media_matched:
rtsp_media = media_matched.get_media()
status = rtsp_media.get_status() #<enum GST_RTSP_MEDIA_STATUS_PREPARED of type GstRtspServer.RTSPMediaStatus>
if "GST_RTSP_MEDIA_STATUS_UNPREPARING" in str(status):
# print(self.context)
# GObject.Object.unref(self)
# print(status)
# transport = media_matched.get_transport(0)
# transport.set_active(False)
# print(enum_list)
# print(rtsp_media.unprepare())
# rtsp_media.set_eos_shutdown(True)
# session.set_timeout(1)
# session.release_media(media_matched)
# session.allow_expire()
# session.release_media(media_matched)
# media_matched.set_state(Gst.State.PAUSED)
# media_matched.set_state(Gst.State.READY)
# media_matched.set_state(Gst.State.NULL)
# rtsp_media.suspend()
# print(rtsp_media.unprepare())
# rtsp_media.set_pipeline_state(Gst.State.READY)
# rtsp_media.set_pipeline_state(Gst.State.NULL)
# rtsp_media.unprepare()
# self.client_filter()
print("removing")
def status_thread_loop(self):
while True:
time.sleep(2)
try:
self.get_status()
except Exception as e:
print(e)
def __del__(self):
print("Destroy called")
def get_current_encoders_details(self):
enc_details = dict()
for i,cap in enumerate(self.caps):
enc_details[i]={"path":self.media_path_list[i],"decoder":cap,"factory":self.factory[i]}
return enc_details
#staticmethod
def get_ip():
return subprocess.check_output("hostname -I", shell=True).decode('utf-8').split(' ')[0]
class encoders():
"""
This is the containter for multiple encoders
"""
def __init__(self,decoders=[],head=[],resolutions=[],suffix="video") -> None:
self.encoder_list = []
self.caps = decoders
self.fps = 60
Sizes = resolutions
self.enc_obj = RTSP_utility_server(self.fps, Sizes=Sizes, speed_preset="medium", caps=decoders, suffix=suffix,
verbosity=1, rtp_port=8554, ip='10.5.1.130')
def get_encoders(self):
return self.enc_obj.get_current_encoders_details()
def set_frame(self,enc_id=0,frame=np.zeros((360, 640, 3))):
encoder_objects = self.enc_obj.get_current_encoders_details()
decoder_obj = None
for id in self.enc_obj.get_current_encoders_details():
if id == enc_id:
decoder_obj = encoder_objects[id]["decoder"]
break
if decoder_obj:
decoder_obj.set_canvas(frame)
else:
print("Decoder not available")
def stop_all(self):
self.enc_obj.stop_all()
def stop_by_index(self,path="/video1"):
self.enc_obj.stop_by_index(path)
def get_status(self):
self.enc_obj.get_status()
the mp queue logic is as following
while True:
# print(f'Thread {self.media_id} Looking')
if self.stop_signal.is_set():
self.stop_signal.clear()
self.active = False
break
ret, frame = self.capture.read()
if ret and type(frame) != type(None):
self.frame = frame.copy()
self.latest_frame = frame.copy()
self.recieving_signal.set()
self.latest_frame_time = time.ctime()
try:
self.frame_queue.put(self.frame,block=False)
except Full:
pass
Here capture is cv2.VideoCapture from an offline file. Is there any way to improve the quality of the video without stuttering with new connections.
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 trying to get the file through FTP protocol using scapy from the specified destination but it is failing even though i am able to create a connection and login to FTP server but file is not retrieved.
'''
! /usr/bin/python2.7
usage: sudo python2.7 client.py [ftp-server-ip]
username and password is currently hardcoded
'''
from scapy.all import *
from random import randint
import sys
class FTPClinet:
def __init__(self, dst):
self.sport = random.randint(1024, 65535)
# self.src = src
self.dst = "90.130.70.73"
self.next_seq = 1000
self.next_ack = 0
self.basic_pkt = IP(src="127.0.0.1",dst=self.dst)/TCP(sport=self.sport, dport=21)
self.tcp_flags = {
'TCP_FIN': 0x01,
'TCP_SYN': 0x02,
'TCP_RST': 0x04,
'TCP_PSH': 0x08,
'TCP_ACK': 0x10,
'TCP_URG': 0x20,
'TCP_ECE': 0x40,
'TCP_CWR': 0x80
}
def send_syn(self):
synack = None
ip = IP(dst=self.dst)
syn = TCP(sport=self.sport, dport=21, flags='S', seq=self.next_seq, ack=self.next_ack)
while not synack:
synack = sr1(ip/syn, timeout=1)
self.next_seq = synack[TCP].ack
return synack
def send_ack(self, pkt):
l = 0
ip = IP(dst=self.dst)
self.next_ack = pkt[TCP].seq + self.get_next_ack(pkt)
ack = TCP(sport=self.sport, dport=21, flags='A', seq=self.next_seq, ack=self.next_ack)
send(ip/ack)
def get_next_ack(self, pkt):
total_len = pkt.getlayer(IP).len
ip_hdr_len = pkt.getlayer(IP).ihl * 32 / 8
tcp_hdr_len = pkt.getlayer(TCP).dataofs * 32 / 8
ans = total_len - ip_hdr_len - tcp_hdr_len
return (ans if ans else 1)
def handshake(self):
synack = self.send_syn()
self.send_ack(synack)
print "sniff called"
sniff(timeout=4, lfilter=self.sniff_filter, prn=self.manage_resp)
print "Handshake complete"
def get_file(self, user, passwd, filen):
user = "USER " + user + '\r\n'
passwd = "PASS " + passwd + '\r\n'
filen = "RETR " +filen + '\r\n'
cwd = "PASV" + '\r\n'
pkt = self.basic_pkt
pkt[TCP].flags = 'AP'
pkt[TCP].seq = self.next_seq
pkt[TCP].ack = self.next_ack
ftp_user = pkt/user
self.send_pkt(ftp_user)
print "userid sent"
pkt[TCP].seq = self.next_seq
pkt[TCP].ack = self.next_ack
ftp_pass = pkt/passwd
self.send_pkt(ftp_pass)
print "password sent"
pkt[TCP].sport = pkt[TCP].sport - 1
pkt[TCP].dport = 20
pkt[TCP].seq = self.next_seq
pkt[TCP].ack = self.next_ack
ftp_filen = pkt/filen
self.send_pkt(ftp_filen)
print "retrieved file"
def sniff_filter(self, pkt):
return pkt.haslayer(IP) and pkt[IP].src==self.dst and pkt.haslayer(TCP) and pkt[TCP].dport == self.sport and pkt[TCP].sport == 21
def manage_resp(self, pkt):
print pkt.show()
if (pkt[TCP].flags == 16L):
self.next_seq = pkt[TCP].ack
elif (pkt[TCP].flags & self.tcp_flags['TCP_ACK']):
self.next_seq = pkt[TCP].ack
self.send_ack(pkt)
elif Raw in pkt:
print "raw packet khamar"
print pkt[Raw]
send_ack(pkt)
else:
print 'Unknown'
print pkt.show()
send_ack(pkt)
def send_p(self,pkt=None):
if pkt:
sr1(pkt)
sniff(timeout=4, lfilter=self.sniff_filter, prn=self.manage_resp)
return
def send_pkt(self, pkt=None):
if pkt:
send(pkt)
sniff(timeout=4, lfilter=self.sniff_filter, prn=self.manage_resp)
return
def close(self):
resp = None
pkt = self.basic_pkt
pkt[TCP].flags = 'FA'
pkt[TCP].seq = self.next_seq
pkt[TCP].ack = self.next_ack
print pkt.show()
while not resp:
resp = sr1(pkt, timeout=4)
# self.send_ack(resp)
self.send_pkt(resp)
h = FTPClinet(sys.argv[1])
h.handshake()
h.get_file("anonymous","","1KB.zip")
h.close()
I am currently building a small socket server in Python, and a web-based client using the WebSocket JavaScript API, and the connection keeps closing after I send the first message.
I tryed connecting to //echo.websocket.org and sending a message and there's no problem there. So as I've read that Error meant a low-level implementation error, I'm assuming that it comes from my server, may am I doing the Handshake wrong. Here is the client code:
function init_game(){
socket = new WebSocket('ws://localhost:3003');
//socket = new WebSocket('ws://echo.websocket.org');
setupSocket();
}
function setupSocket(){
socket.onopen = function(){
console.log('Connection open !');
var msg = {cmd: 'hello', params: {}};
var data = JSON.stringify(msg);
console.log('Sending : ' + data);
socket.send(data);
};
socket.onmessage = function(e){
var data = e.data;
console.log('Received : ' + data);
handle(data);
};
socket.onerror = function(e){
console.log('ERROR : ' + e.code + " - " + e.reason);
};
socket.onclose = function(e){
console.log('CONNECTION CLOSED : ' + e.code + " - " + e.reason);
}
}
function handle(data){
//doing stuff
}
window.onload = init_game;
And here the server code:
class ClientThread(threading.Thread):
# Constructor
def __init__(self, conn, id, q):
threading.Thread.__init__(self)
self.conn_ = conn
self.id_ = id
self.name_ = ''
self.q_ = q
self.handshaken_ = True
self.encoded_ = False
# Main loop
def run(self):
raw_data = self.conn_.recv(1024)
if raw_data[:3] == 'GET':
self.handshaken_ = False
self.handshake(raw_data)
while True:
raw_data = self.conn_.recv(1024)
if len(raw_data) == 0:
continue
if self.handshaken_:
if self.encoded_:
raw_data = self.decode(raw_data).decode('utf-8')
try:
data = json.loads(raw_data)
cmd = data['cmd']
params = data['params']
self.handle(cmd, params)
except ValueError, e:
print 'Data received was not JSON'
else:
print 'Received something but Handshake is not done yet... Something is going wrong.'
# Decode encoded message received frmo the client
def decode(self, data):
frame = bytearray(data)
length = frame[1] & 127
indexFirstMask = 2
if length == 126:
indexFirstMask = 4
elif length == 127:
indexFirstMask = 10
indexFirstDataByte = indexFirstMask + 4
mask = frame[indexFirstMask:indexFirstDataByte]
i = indexFirstDataByte
j = 0
decoded = []
while i < len(frame):
decoded.append(frame[i] ^ mask[j%4])
i += 1
j += 1
return "".join(chr(byte) for byte in decoded)
# Performs handshake protocole in case it's needed
def handshake(self, get):
websocket_answer = (
'HTTP/1.1 101 Switching Protocols',
'Upgrade: websocket',
'Connection: Upgrade',
'Sec-WebSocket-Accept: {key}\r\n\r\n',
)
GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
raw_key = re.search('Sec-WebSocket-Key:\s+(.*?)[\n\r]+', get)
if raw_key != None:
# Create Handshake answer...
key = raw_key.groups()[0].strip()
handshake_key = b64encode(sha1(key + GUID).digest())
handshake = '\r\n'.join(websocket_answer).format(key=handshake_key)
# And send it to the client
self.conn_.send(handshake)
self.handshaken_ = True
self.encoded_ = True
else:
print 'No key found during Handshake.'
self.disconnect()
# Handle JSON commands send by the client
def handle(self, cmd, params):
# doing stuff
def disconnect(self):
print 'Disconnecting.'
pass
class MainServer(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.HOST = ''
self.PORT = 3003
self.socket_ = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.socket_.bind((self.HOST, self.PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
self.clients_ = {1: Player(1), 2: Player(2)}
self.q_ = Queue()
def run(self):
self.socket_.listen(10)
nb_player = 0
new_id = 1
while nb_player < 2:
conn, addr = self.socket_.accept()
print 'A new player connected with ' + addr[0] + ':' + str(addr[1])
self.clients_[new_id].conn = conn
th = ClientThread(conn, new_id, self.q_)
th.start()
new_id += 1
nb_player += 1
while True:
data = self.q_.get(block=True)
self.handle(data['cmd'], data['params'])
def handle(self, cmd, params):
# doing stuff
if __name__ == '__main__':
serv = MainServer()
serv.start()
Please tell me if you need any other information.
Thanks !
Robin
I've programmed a python script to backup my files, something like Dropbox.
But there are some bugs. I have a class called SyncServer, and there are two functions called __init__ and TF1 seperately. TF1 stands for "Thread Function 1".
When I write thread.start_new_thread(TF1, (conn, 0)), the first parameter, I sent a socket object in. Unfortunately, python's IDLE replied with an error: NameError: global name 'TF1' is not defined
# -*- coding: cp950 -*-
import wx, socket, os, md5, thread, threading
class SyncClient:HOST = "127.0.0.1"
def __init__(self):
self.config = {}
open("sync.config", "a").close()
f = open("sync.config", "r")
line = f.readline()
while line:
tmp = line.split(":")
self.config[tmp[0]] = ":".join(tmp[1:]).split("\n")[0]
line = f.readline()
f.close()
ex = wx.App()
ex.MainLoop()
if (not self.config.has_key("id")) or (not self.config.has_key("password")) or (not self.config.has_key("port")) or (not self.config.has_key("path")):
wx.MessageBox('something wrong. Q__________________________Q', 'Error',
wx.OK | wx.ICON_ERROR)
return
if (not os.access(self.config["path"], os.F_OK)):
wx.MessageBox("It seems that " + self.config["path"] + " doesn't exist.", 'Error',
wx.OK | wx.ICON_ERROR)
return
if int(self.config['port']) > 5:
wx.MessageBox('something wrong. Q__________________________Q', 'Error',
wx.OK | wx.ICON_ERROR)
return
chpswd = md5.new(self.config['password']).hexdigest()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((self.HOST, 7575))
self.s = s;
s.send("CHECK ID")
if s.recv(1024) != "200 OK":
return
s.send(config['id'] + ";;" + chpswd)
if s.recv(1024) == "False":
wx.MessageBox("id and password not match.", 'Error',
wx.OK | wx.ICON_ERROR)
return
self.path = []
for root, dirs, files in os.walk(self.config['path']):
for f in files:
self.path.append(root + f)
self.s.send("FILE NAME")
if self.s.recv(1024) != "200 OK":
continue
self.s.send(f)
if self.s.recv(1024) != "200 OK":
continue
self.s.send("FILE LEN")
if self.s.recv(1024) != "200 OK":
continue
cut = file_cut(root + f)
self.s.send(len(cut))
MakeThread(cut)
def MakeSocket(self):
self.s.send("GIVE ME A PORT")
port = int(self.s.recv(1024))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((self.HOST, port))
return s
def MakeThread(self, cut):
self.ptr = 0
s = MakeSocket()
for i in self.config['port']:
#s = MakeSocket()
thread.start_new_thread(TF, (s, cut))
def TF(self, Socket, cut):
l = len(cut)
while self.ptr < l:
Socket.send(self.ptr)
if Socket.recv(1024) != "200 OK":
continue
Socket.send(cut[self.ptr])
self.ptr += 1
Socket.close()
def file_cut(self, path):
f = open(path, "rb")
content = f.read()
cut = []
l = len(content)
i = 0
while i < l:
cut.append(content[i:i+1024])
i += 1024
return cut
'''f = open(path, "rb")
cont = f.read()
f.close()
fsize = len(cont)
fname = path.split("\\")[-1]
self.com.send(fname)
check = self.com.recv(1024)
if check != "200 OK": return
self.com.send(str(fsize))
check = self.com.recv(1024)
if check != "200 OK": return
i = 0
while i < fsize + 1025:
Socket.send(cont[i:i+1024])
i += 1024'''
def file_recv(self, Socket, path=".\\"):
fname = self.com.recv(1024)
self.com.send("200 OK")
f = open(path + fname, "wb")
fsize = self.com.recv(1024)
self.com.send("200 OK")
i = 0
while i < fsize + 1025:
line = Socket.recv(1024)
f.write(line)
f.flush()
i += 1024
f.close()
class SyncServer:
def TF1(self, Socket, null):
while True:
data = Socket.recv(1024)
if data == "CHECK ID":
Socket.send("200 OK!")
user = Socket.recv(1024)
u = open("uid.txt","r")
while True:
udata = u.readline().split(" ")
if udata == "":
Socket.send("False")
break
if user.split(";;")[0] == udata[0]:
Flag = True
if user.split(";;")[1] != md5.hexidigest(udata[1]):
Socket.send("False")
else:
self.user = user.split(";;")[0]
self.files[self.user] = []
Socket.send("True")
break
if data == "GIVE ME A PORT":
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", self.portList[0]))
s.listen(1)
Socket.send(self.portList[0])
for i in range(0, flen):
thread.start_new_thread(TF2, (s.accept(), 0))
f = open(fname, "wb")
for line in self.files[self.user]:
f.write(line)
f.close()
#self.port
if data == "FILE NAME":
Socket.send("200 OK")
fname = Socket.recv(1024)
Socket.send("200 OK")
if data == "FILE LEN":
Socket.send("200 OK")
flen = int(Socket.recv(1024))
def TF2(self, Socket, null):
idx = Socket.recv(1024)
Socket.send("200 OK")
line = Socket.recv(1024)
self.files[self.user][idx] = line
def __init__(self):
self.portList = []
self.files = {}
for i in range(7576,7700):
self.portList.append(i)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", 7575))
s.listen(1)
while True:
conn, addr = s.accept()
thread.start_new_thread(TF1, (conn, 0))
thread.start_new_thread(TF1, (conn, 0))
Assumes that TF1 is a global.
"NameError: global name 'TF1' is not defined"
States that TF1 is not a global.
It must be that the assumption is wrong.
TF1 is a method function in a class. Therefore, it needs to be qualified either by the class name or by an object instance. Usually, self.TF1 is appropriate.
Please find a Python tutorial where class definitions are covered.