I have a GUI and i need to be able to open a server socket that listens to incoming traffic, but when I try to join the server thread it gives an error:
RuntimeError: cannot join current thread
Here is the relevant code:
def create_widgets(self):
...other widgets...
self.thread1 = threading.Thread(target = self.serverstart)
self.button2 = Button(text = "Start", command = self.thread1.start)
self.button2.grid(row=2, column=3)
def serverstart(self):
import tcpServer
tcpServer.start(self.intip)
self.thread1.join()
Here is the code for tcpServer:
import socket
def start(intip):
host = intip
port = 5000
s = socket.socket(socket.AF_INET6)
s.bind((host, port))
s.listen(1)
c, addr = s.accept()
print "Connection from: " + str(addr)
while True:
data = c.recv(1024)
if not data:
break
print "from connected user: " + str(data)
data = str(data).upper()
print "sending: " + str(data)
c.send(data)
c.close()
if __name__ == '__main__':
start()
Thank you in advance for your help
RuntimeError: cannot join current thread means that the current thread is trying to join itself.
Indeed, you launch your thread routine (bound method serverstart) and store the returned thread. That routine, then, attempts to join that thread ... which is itself. RuntimeError
Related
When I disconnect all clients in server, server doesn't continue live. How can I do for living server
import socket, threading, tkinter
Server
import socket, threading, tkinter
import time
def sendDisconnectAll(my_clients):
for client in my_clients:
conn = client[0]
conn.sendall('Disconnect'.encode('utf8'))
conn.close()
def handle_client(conn, addr):
while True:
try:
request_from_clients = conn.recv(1024).decode('utf8') #sample request
print(request_from_clients)
if request_from_clients == 'SignIn':
conn.sendall('Accept Sign in'.encode('utf8'))
except:
print('Client has been shutdown')
break
my_clients = []
def live_server():
global thr
global s
while True:
try:
conn, addr = s.accept()
my_clients.append((conn, addr))
thr = threading.Thread(target=handle_client, args=(conn, addr))
thr.daemon = True
thr.start()
except:
print("Error")
HOST = '127.0.0.1'
PORT = 8000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen()
print('HOST: ', HOST)
print('PORT: ', PORT)
thr = threading.Thread(target=live_server)
thr.daemon = True
thr.start()
count_time = time.time()
while True:
now = time.time()
if (int(now - count_time) + 1) % 10 == 0: #Disconnect all clients after 10 seconds
count_time = now
request = 'Disconnect'
print('Disconnect all')
sendDisconnectAll(my_clients)
Clients
import socket, threading
import tkinter as tk
from tkinter import *
def signIn():
global client
request = 'SignIn'
try:
client.sendall(request.encode('utf8'))
client.recv(1024).decode('utf8')
except:
print('Server has been shutdown')
IP = input("Enter IP: ")
PORT = input("Enter PORT: ")
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client.connect((IP, int(PORT)))
except:
print("Can't connect to server")
client.close()
def live_client():
global client
while True:
print(client.recv(1024).decode('utf8'))
thr = threading.Thread(target=live_client)
thr.daemon = True
thr.start()
app = Tk()
app.title('CLIENT')
but_connect = tk.Button(app, text="SIGN IN",
width=20, command=signIn)
but_connect.pack(pady=6)
app.mainloop()
Thank you!
The problem is that you only add clients to the my_clients list. Let's look what happens in server:
server starts
it receives one client an adds it to my_clients
on next disconnect all operation the socket for that client is closed, but the client remains on the list
on the following disconnect all operation, the main thread of the server tries to write to a closed socket and raises an exception
as all other threads are daemonic, the application ends.
You must clear the my_clients list after closing all the client sockets:
def sendDisconnectAll(my_clients):
for client in my_clients:
conn = client[0]
conn.sendall('Disconnect'.encode('utf8'))
conn.close()
my_clients.clear()
Beware: I did not look at client code...
In this code, When I tried without applying multithreading on python socket, it works perfectly fine. But after using multithreading for concurrency, the first while loop works fine, but in the 2nd while loop, it takes it as 2nd thread, which doesn't complete the procedure of sending passkey to android. Here, I dont want 2nd loop as 2nd thread. How will I do that ? Any help will be appreciated!
import mysql.connector as mysql
import socket
import sys
import json
import threading
mydb1=mysql.connect(
user = 'rajat',
passwd = 'rajat',
host = 'localhost',
database = 'master_database'
)
class ClientThread(threading.Thread):
def __init__(self,clientAddress,clientsocket):
threading.Thread.__init__(self)
self.csocket = clientsocket
self.addr = clientAddress
print ("New connection added: ", clientAddress)
def run(self):
print ("Connection from : ", self.addr)
#self.csocket.send(bytes("Hi, This is from Server..",'utf-8'))
msg = ''
while True:
#csocket, clientAddress = s.accept()
#print ('Connect with ' + addr[0] + ':' + str(addr[1]))
df7 = self.csocket.recv(1024)#Receiving the data in df7
df8 = json.loads(df7)
df2 = list(df8.values())
mycursor4=mydb1.cursor()
mycursor4.execute("SELECT bar_code_no FROM form_simpleform")
obj1 = mycursor4.fetchone()
qr_obj=print(obj1[0])
mycursor3 = mydb1.cursor()
mycursor3.execute("SELECT bar_code_no FROM bar_code")
obj2 = mycursor3.fetchone()
bar_obj=print(obj2[0])
if qr_obj == bar_obj:
print("This bar code has a existence in the database.")
else:
print("This bar code does not exist.")
mycursor1=mydb1.cursor()
mycursor1.execute("SELECT * FROM form_simpleform WHERE id=1")
df3=mycursor1.fetchone()
if df2 == (list(df3)):
print('Data of QR Code also Exists')
mycursor2 = mydb1.cursor()
mycursor2.execute("SELECT * FROM android_display_data")
df4 = mycursor2.fetchone()
self.csocket.send(str(df4).encode('utf-8'))
print("Data(Name, Email_id, Phone_No) is sent to the client ")
self.csocket.close()
message=[]
while True:
clientsock, clientAddress = s.accept()
message = self.csocket.recv(1024).decode('ISO-8859-1')
print("Received new message from client")
op=((message).split(","))
print(op)
d = dict(s.split(':') for s in op)
yo = print(list(d.values()))
mycursor5 = mydb1.cursor()
sql2 = ("INSERT INTO imeiserial (IMEI, SimSerialNumber) VALUES (%s, %s)")
result = mycursor5.execute(yo, sql2)
print("Data inserted into bar_code Database")
pass_key = '90i5n4r16191'
self.csocket.send(str(pass_key).encode('utf-8'))
print(" Passkey send to Android ")
break
else:
print('Invalid Data')
break
print('Connection Closed!!')
#s.close()
LOCALHOST = "192.168.0.121"
PORT = 8011
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((LOCALHOST, PORT))
print("Server started")
print("Waiting for client request..")
while True:
s.listen(5)
clientsock, clientAddress = s.accept()
newthread = ClientThread(clientAddress, clientsock)
newthread.start()
The Output which I am getting-
Server started
Waiting for client request..
Connection from : ('192.168.0.108', 42762)
456456
456456
This bar code has a existence in the database.
Data of QR Code also Exists
Data(Name, Email_id, Phone_No) is sent to the client
Connection from : ('192.168.0.108', 42764)
Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\Users\Pallavai\Nox_share\AnacondaNEW\lib\threading.py", line 917, in _bootstrap_inner
self.run()
File "server-side2.py", line 34, in run
df8 = json.loads(df7)
When you run ClientThread class you are trying to call for clientAdress variable that is never defined in your current scope.
def run(self):
print ("Connection from : ", clientAddress)
Henceforth clientAdress throws an error. To way to solve this is, assign clientAddress during init method then call it via self.clientAddress.
class ClientThread(threading.Thread):
def __init__(self,clientAddress,clientsocket):
threading.Thread.__init__(self)
self.csocket = clientsocket
self.addr = clientAddress
print ("New connection added: ", clientAddress)
def run(self):
print ("Connection from : ", self.addr)
I am trying to check if data is available on one port. If this it is avaiable then a message "yes" should be sent to another port and "no" if there is no data.
A client is connecting to that port where "yes" or "no" is coming. I run the script and every thing looked fine. But after one hour I got the error:
Runtime error can not start new thread. Exception in Thread 11:
Traceback< most recent call last: file threading.py line 914 in boot strap-inner.
I am new to python and I really do not understand what is going on. My code contains many threads as I am checking data from 10 ports and sending "yes" or "no" message to other 10 ports.
Here is a part of my code for 1 port:
import time
import socket
import threading
from threading import Thread
import select
#-----------------------------------Server --------------------------
s = socket.socket(socket.AF_INET) #Socket
h = '127.0.0.1' #Host where data coming from
p = 14201 #Port
halarm = "127.0.0.1" # A port will be opened to send availabilty status
palarm = 14202 # Port
def Server ():
while True:
try:
time.sleep(0.1)
s.connect((h, p))
except socket.error:
pass
#-----------------------------------Server/Client -------------------------------
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind((halarm, palarm)) # Bind to the Port where
sock.listen(1)
def func(conn): # Server-Client Function
while True:
try:
global s
Timeout = select.select([s], [], [], 5)# Timeout in seconds
connected = True
while True:
try:
if Timeout[0]:
conn.send(bytes("yes", "utf-8"))
time.sleep(3)
else:
conn.send(bytes("no", "utf-8"))
time.sleep(3)
newConnection= False
while not newConnection:
try:
s = socket.socket(socket.AF_INET)
s.connect((h, p))
Timeout = select.select([s], [], [], 5)# Timeout in seconds
newConnection= True
except socket.error:
conn.send(bytes("Port is closed", "utf-8"))
time.sleep(3)
pass
except socket.error:
pass
except:
pass
def connThread():
while True:
conn, addr = sock.accept()
time.sleep(0.1)
Thread(target = func, args=(conn,)).start()
if __name__ == '__main__':
Thread(target = Server).start()
Thread(target = connThread).start()
How can I solve this problem ? I appreciate all your help.
I am trying to set up a tcp server in Python using Multithreading. The problem is that the queue only return data from only one thread. That means it only prints the data from the thread created with 5555 or 5556. I confirmed both data reaches port by connecting one device per time but it does not print the result from connection to the other port when more than one device connected.
Thanks for your help.
#!usr/bin/python
from threading import Thread
import socket
import sys
from queue import Queue
def clientthread(conn,q):
buffer=""
data = conn.recv(8192)
buffer=data
q.put(buffer)
return buffer
def main():
try:
host = '169.254.162.144'
port = 5555
tot_socket =2
list_sock = []
conarr=[]
threads=[]
for i in range(tot_socket):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind((host, port+i))
s.listen(10)
list_sock.append(s)
print ("[*] Server listening on %s %d" %(host, (port+i)))
for j in range(len(list_sock)):
conn, addr = list_sock[j].accept()
conarr.append(conn)
print('[*] Connected with ' + addr[0] + ':' + str(addr[1]))
while 1:
queue1 = Queue()
for j in range(len(list_sock)):
thread =Thread( target=clientthread, args=(conn, queue1) )
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
while not queue1.empty():
result = queue1.get()
print(result)
threads=[]
s.close()
except KeyboardInterrupt as msg:
sys.exit(0)
if __name__ == "__main__":
main()
I am trying to listen on a port for specific message being transmitted to stop my program.
Here is the function that is listening using sockets:
def receive():
host = ""
port = 13000
buf = 1024
addr = (host,port)
Sock = socket(AF_INET, SOCK_DGRAM)
Sock.bind(addr)
(data, addr) = Sock.recvfrom(buf)
return data
I have made it run in the background with threading:
while True:
r = threading.Thread(target=receive)
r.start()
if r == "stop":
print "Stopped"
break
print "Running program"
When the r = threading is inside the while loop, as above, I get:
error: [Errno 98] Address already in use
And when I define r = threading outside the while loop (before it), I get:
RuntimeError: threads can only be started once
I have tried this, however when I send the "stop" command it sends the thread RuntimeError AND quits the program:
if r.is_alive == False:
r.start()
If you insist on using threading:
from socket import *
def receive():
host = ""
port = 13000
buf = 1024
addr = (host,port)
Sock = socket(AF_INET, SOCK_DGRAM)
Sock.bind(addr)
while True:
(data, addr) = Sock.recvfrom(buf)
if data == "stop":
print "Stopped"
break
print "Running program"
import threading
r = threading.Thread(target=receive)
r.start()
r.join()