Runtime error can not start new thread - python

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.

Related

How to send request disconnect from server to all clients and server still live (python socket)

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...

How can I receive multiple messages from one connection?

I have a server and I need it to receive multiple connections and messages.
The server receives new connections without problems but it doesn't get multiple messages from one connection.
import socket
import select
HEADER_LENGTH = 1024
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
server_socket.bind((HOST, PORT))
except socket.error as e:
print(str(e))
print("Server is connected")
server_socket.listen(5)
sockets_list = [server_socket]
clients = {}
print("Server is listening")
def receive_message(conn):
try:
data = conn.recv(HEADER_LENGTH)
if not len(data):
return False
strdata = data.decode('utf-8')
print(strdata)
return strdata
except Exception as e:
print(e)
return False
def handle_client():
conn, addr = server_socket.accept()
print(f"Accepted new connection from {addr[0]}:{addr[1]}")
sockets_list.append(conn)
while True:
read_sockets, _, exception_sockets = select.select(sockets_list, [], [], 0)
for i in read_sockets:
if i == server_socket:
handle_client()
else:
print("received message")
message = receive_message(i)
if message is False:
sockets_list.remove(i)
try:
del clients[i]
except KeyError:
pass
continue
if message is not None:
clients[i] = message
if message is not None:
for client_socket in clients:
if client_socket != i:
client_socket.send(str.encode(message))
print("sent to all players")
What happens it that after receiving the first message, the server stops receiving messages from that connection.
And of course there is a lot more code but I showed you the relevant code.
I'll be very happy if someone helps me with that, I've surfed the web so much but haven't seen a solution for my problem.
updates:
I've tried to put socket.close() on my client side(written in Java) and then server gets maximum 2 messages and the problems with it are:
1. The server gets maximum 2 messages.
2. the connection changes(I need that the connection will stay static if possible)
try this code block
#-*- coding:utf-8 -*-
import socket
import sys
#get machine ip address
server_ip = socket.gethostbyname(socket.gethostname())
#create socket object
s = socket.socket()
#define port number
port = 6666
#bind ip and port to server
s.bind((server_ip,port))
#now waiting for clinet to connect
s.listen(5)
print("Enter this ip to connect your clinet")
print(server_ip)
clients = []
flag = True
recv_data = ""
if not clients:
c, addr = s.accept()
print("this is c ",c," this is Addr ",addr)
clients.append(c)
recv_data = c.recv(1024)
print(recv_data.decode("utf-8"))
if flag == True:
while recv_data.decode("utf-8") != "EX":
recv_data = c.recv(1024)
recv_data.decode("utf-8")
if recv_data.decode("utf-8") == "EX":
s.close()
print("check false")
break
s.close()

Thread a server to accept more than one client doesn't work properly

Well, I'm trying to make a simple Network TCP chatting program to dive deeper in python, threading and networking. The program worked but with just one user, I looked this up, I found that I need threading to make the server accept more than one user. I threaded the server but now when you connect the second user it disconnect the first one. Source code may not be that good..
#!/usr/bin/python
import socket, sys, threading
from time import sleep
# Global Stuff
localhost = socket.gethostbyname(socket.gethostname())
#localhost = '192.168.x.x'
serverPort = 5003
buffer = 1024 #Bytes
backlog = 5
userThread= []
count = 0
class server(object):
''' Constructor to Establish Bind server once an object made'''
def __init__(self, localhost, serverPort): # Connect Tcp
global backlog, count
self.servSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.servSock.bind((localhost, serverPort))# bind((host,Port))
self.servSock.listen(backlog)
print count
except Exception, e:
print "[Bind ]", e
sys.exit()
def accept(self):
global userThread, conn, addr, count
"""
- PROBLEM IS IN HERE SOMEWHERE SERVER DOESN'T ADD THE OTHER CLIENT EXCEPT ONCE.
- THREAD DOEN'T KEEP THE CLIENT.
- THE SECOND CLIENT FREEZES WHILE SENDING THE VERY FIRST MESSAGE TILL THE FIRST
CLIENT SEND A MESSAGE THEN IT CAN SEND MESSAGES AND THE FIRST CLIENT CAN'T SEND SHIT.
"""
count+=1
while True:
print count
self.conn, self.addr = self.servSock.accept()
conn = self.conn
print("This is a connection: ", conn)
#acceptThread = threading.start_new_thread(target=serverObj.accept, args=(conn))
#addr = self.addr
print "[Listening..]"
if(self.addr not in userThread):
userThread.append(self.addr)
print "Client's added Successfully"
else:
pass
def redirect(self):
global buffer, userThread, conn, count
count+=1
while True:
try:
print "Redirecting " + str(count)
self.data = conn.recv(buffer)
if self.data:
for user in userThread:
#conn.send(b'Recieved by server!\n')
conn.sendto("Sent!\n"+self.data+"\n", user)
print "Server: Data sent[" +self.data+"] to ["+str(user)+"]"
else:
self.data = conn.recv(buffer)
print "No dataa found"
except Exception, e:
print "[Redirect ] ",e
sleep(7)
print "OUT"# testing if it's getting out this infinite loop.
def exit(self):
self.server.close()
def main():
global localhost, serverPort, conn
try:
serverObj = server(localhost, serverPort)
print("[+] Server is UP!")
except Exception, e:
print "[Main ] ",e
exit()
acceptThread = threading.Thread(name = "Accepting Connections", target=serverObj.accept)
redirThread = threading.Thread(name = "Redirecting Data", target=serverObj.redirect)
acceptThread.start()
redirThread.start()
print userThread
main()
######################################### Client ##########################################
#!/usr/bin/python
# This is client file
"""
http://eli.thegreenplace.net/2011/05/18/code-sample-socket-client-thread-in-python
https://docs.python.org/2/library/threading.html
"""
import socket
import threading
from time import sleep
# Client Info
#clientSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#localhost = '192.168.x.x'
# Global Stuff
serverIP = socket.gethostbyname(socket.gethostname())
#serverIP = '192.168.x.x'
serverPort, MsgSendError, MsgSendSucc, clientPort, data, buffer =\
5003, False, True, 12345, '',1024 #Bytes
class client(object):
global MsgSendError, MsgSendSucc, buffer, data
''' Constructor to Establish Connection once client is up'''
def __init__(self, serverIP, serverPort): # Connect Tcp
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.sock.connect((serverIP, serverPort))
except Exception, e:
return "[Connecting to Server]", e
def send(self, data):
try:
self.sock.send(data) # covnert it from string into byte streams to be in proper format.
#print str(data)
return MsgSendSucc
except:
return MsgSendError
def receive2(self):
try:
data = self.sock.recv(buffer)
#print "Function: Receive2."# testing
#print(str(data))# testing
#print "Received!"# testing
return str(data)
except Exception, e:
return "[In receive2]", e
def main():
global serverIP, serverPort, data#, sock
clientObj = client(serverIP, serverPort)
alias = raw_input("Your Name USER! ")
sentData = ''
while sentData is not 'Quit':
sentData = raw_input("Data>> ")
data = alias + ": "+sentData
if clientObj.send(data) == MsgSendSucc:
#print "Sent!"
#print "Fetching..\n"# testing
print(clientObj.receive2())
# testing
main()

Listening for specific data whilst using threading

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()

How do I allow more simultaneous socket connections?

I'm attempting to implement the Reactor pattern in Python. I think I have a pretty decent start using multiprocessing and select.select. However, I'm trying to stress-test my server, so I wrote a simple DoS client to flood it with connections. But I get an interesting error:
[WinError 10061] No connection could be made because the target machine actively refused it
The interesting thing about this is that I'm doing socket.listen(5) for the backlog amount on the server. After I get readers ready from select.select I display the count, and I only ever have 1 or 2 - not the 5 that I would expect.
For a small number of threads (~20) I haven't noticed it choke, but for a larger number (50+) it does tend to refuse connections.
Is my problem on the server or client side (or just at the OS/socket level)? Is this a problem that I can fix? And if so, how?
Here is my code:
Client
import threading
import time
import socket
from contextlib import contextmanager
IP = '127.0.0.1'
PORT = 4200
#contextmanager
def open_socket(ip, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.connect((ip, port))
yield sock
finally:
sock.close()
class Flood(threading.Thread):
def __init__(self, id):
super(Flood, self).__init__()
self.id = id
self.failed = False
def run(self):
try:
with open_socket(IP, PORT) as sock:
msg = "Hello this is some data from %d" % self.id
sock.send(msg.encode())
except Exception as e:
print(e)
self.failed = True
def make_threads(count):
return [Flood(_) for _ in range(count)]
threads = make_threads(5000)
start = time.time()
for t in threads:
t.start()
for t in threads:
t.join()
print("Failed: ", sum(1 if x.failed else 0 for x in threads))
print("Done in %f seconds" % (time.time() - start))
Server
import sys
import logging
import socket
import select
import time
import queue
from multiprocessing import Process, Queue, Value
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)
log.addHandler(logging.StreamHandler())
IP = '127.0.0.1'
PORT = 4200
keep_running = True
def dispatcher(q, keeprunning):
try:
while keeprunning:
val = None
try:
val = q.get(True, 5)
if val:
log.debug(val[0].recv(1024).decode())
val[0].shutdown(socket.SHUT_RDWR)
val[0].close()
except queue.Empty:
pass
log.debug("Dispatcher quitting")
except KeyboardInterrupt:
log.debug("^C caught, dispatcher quitting")
def mainloop(sock):
readers, writers, errors = [sock], [], []
timeout = 5
while True:
readers, writers, errors = select.select(readers,
writers,
errors,
timeout)
incoming = yield readers, writers, errors
if incoming and len(incoming) == 3:
readers, writers, errors = incoming
if not readers:
readers.append(sock)
def run_server():
keeprunning = Value('b', True)
q = Queue()
p = Process(target=dispatcher, args=(q, keep_running))
try:
p.start()
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((IP, PORT))
sock.listen(50)
sock.setblocking(0)
loop = mainloop(sock)
for readers, writers, errors in loop:
if readers:
client, addr = readers[0].accept()
q.put((client, addr))
log.debug('*'*50)
log.debug('%d Readers', len(readers))
log.debug('%d Writers', len(writers))
log.debug('%d Errors', len(errors))
except KeyboardInterrupt:
log.info("^C caught, shutting down...")
finally:
keeprunning.value = False
sock.close()
p.join()
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: test.py (client|server)")
elif sys.argv[1] == 'client':
run_client()
elif sys.argv[1] == 'server':
run_server()
I tried to test your code, but failed on import queue.
Nevertheless, it might be that
your OS acts as the listen() function is specified: "Implementations may impose a limit on backlog and silently reduce the specified value."
your OS stops accepting the connection as soon there are enough incomplete connections, which might not be displayed upon request.
These are just guesses about what might be the reason; maybe I am completely wrong.

Categories