Python Socketserver client timeout - python

I have a socketserver in Python which has to handle multiple clients using the select.select method, as seen in the code below:
import socket
import select
class Server:
def __init__(self):
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind(('localhost', 2000))
self.socket_list = [self.server]
self.addresses = ['localhost']
self.commands = [""]
self.running = True
self.server.listen(10)
def listen(self):
while self.running:
read, write, error = select.select(self.socket_list, [], self.socket_list, 0)
for sock in read:
if sock == self.server and self.running:
try:
conn, address = self.server.accept()
conn.settimeout(30)
self.socket_list.append(conn)
self.addresses.append(address[0])
self.commands.append("")
except:
self.shutdown()
break
elif self.running:
try:
packet = sock.recv(60)
if not packet:
self.close_conn(sock)
index = self.socket_list.index(sock)
self.commands[index] += packet
if '\n' in self.commands[index]:
#handle command
except:
self.close_conn(sock)
def close_conn(self, conn):
#close client conn
def shutdown(self):
#shutdown server
if __name__ == "__main__":
Server().listen()
The problem i currently have is that the client's connection should be closed after 30 seconds, but that doesn't happen, even though i declared that by using conn.settimeout(30). I haven't found any explanation yet as to why this happens.
Note: comments were used to replace parts of the code that didn't mater to the problem.

Related

Socket not closing when shutting down a thread

In the below code, although the thread seems to be stopping the socket does not seem to be freed. Not sure what mistake I am making.
When I try to start the second time it is throwing an error 'Address already in use'. I looked up a lot of stack overflow suggestions, did not help much.
Here is my code:
import threading
import time
import socket
class TCPServer(object):
def __init__(self):
self.stop_thread = threading.Event()
def startServer(self, ip="localhost", port=12345):
self.ip = ip
self.port = port
t = threading.Thread(target=self.server, args=(self.stop_thread,
"stop_event"))
t.daemon = True
t.start()
def server(self, stop_event, arg):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((self.ip, self.port))
sock.listen(5)
connection = ""
while not stop_event.is_set():
connection, addr = self.sock.accept()
data = connection.recv(50000)
if data:
connection.send(self.response)
connection.close()
#Tried with below statements - still fails
#self.sock.shutdown(socket.SHUT_RDWR)
#self.sock.close()
def stopServer(self):
self.stop_thread.set()
if __name__ == "__main__":
server = TCPServer()
server.startServer("localhost", 12345)
time.sleep(5)
server.stopServer()
time.sleep(15)
server.startServer("localhost", 12345)
time.sleep(5)
server.stopServer()
I found a work around by forcefully shutting down the socket in stopServer() like below:
def stopServer(self):
self.stop_thread.set()
self.sock.shutdown(socket.SHUT_RDWR)
self.sock.close()
But I dont think this is a good solution. Any suggestions?
import threading
import time
import socket
class TCPServer(object):
def __init__(self):
self.stop_thread = threading.Event()
def startServer(self, ip="localhost", port=12345):
self.ip = ip
self.port = port
t = threading.Thread(target=self.server, args=(self.stop_thread,
"stop_event"))
t.daemon = True
t.start()
def server(self, stop_event, arg):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.bind((self.ip, self.port))
self.sock.listen(5)
connection, addr = self.sock.accept()
while not stop_event.is_set():
data = connection.recv(50000)
if data:
connection.send(self.response)
connection.close()
self.sock.close()
def stopServer(self):
self.stop_thread.set()
so mostly minor things that accumulated. You needed to check if event is set, not just if event was true. You can read more on that in event-object docs. That meant you never left the inner loop. Once you leave the inner loop you need to close both connection and the socket explicitly.

Socket While True Loop Doesn't Work Properly

I want to ask you about while loop in socket works.
The problem is, when i started app, the server is waiting for connections by While True. But if anyone connect, server won't accept another connections. The While True loop freezes.
My Code:
import socket
import threading
class Server(object):
def __init__(self, host="localhost", port=5335):
"""Create socket..."""
self.host = host
self.port = port
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.bind((self.host, self.port))
self.sock.listen(0)
self.clients = []
print("Server is ready to serve on adress: %s:%s..."%(self.host, self.port))
while True:
client, addr = self.sock.accept()
print("There is an connection from %s:%s..."%addr)
t = threading.Thread(target=self.threaded(client, addr))
t.daemon = True
t.start()
self.sock.close()
def threaded(self, client, adress):
"""Thread client requests."""
while True:
data = client.recv(1024)
print("%s:%s : %s"%(adress[0], adress[1], data.decode('ascii')))
if not data:
print("Client %s:%s disconnected..."%adress)
break
if __name__ == "__main__":
Server()
You aren't calling the thread properly. You're calling self.threaded(client, addr) immediately and then passing the result to threading.Thread().
In other words, this:
t = threading.Thread(target=self.threaded(client, addr))
... is identical to this:
result = self.threaded(client, addr)
t = threading.Thread(target=result)
You need to call it like this:
t = threading.Thread(target=self.threaded, args=(client, addr))

Python - multithreaded sockets

From my understanding python can only run 1 thread at a time so if I were to do something like this
import socket, select
from threading import Thread
import config
class Source(Thread):
def __init__(self):
self._wait = False
self._host = (config.HOST, config.PORT + 1)
self._socket = socket.socket()
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._sock = None
self._connections = []
self._mount = "None"
self._writers = []
self._createServer()
Thread.__init__(self)
def _createServer(self):
self._socket.bind(self._host)
self._socket.listen(2)
self._connections.append(self._socket)
self._audioPackets=[]
def _addPacket(self, packet):
self._audioPackets.append(packet)
def _removePacket(self, packet):
self._audioPackets.remove(packet)
def _getPacket(self):
if len(self._audioPackets) > 0:
return self._audioPackets[0]
else:
return None
def _sendOK(self, sock):
sock.send("OK")
def _sendDenied(self, sock):
sock.send("DENIED")
def _sendMount(self, sock):
sock.send("mount:{0}".format(self._mount))
def _sendBufPacket(self, sock, packet):
packet = "buffer:%s" % packet
sock.send(packet)
def recv(self, sock, data):
data = data.split(":", 1)
if data[0] == "WAIT": self._wait = True
elif data[0] == "STOP_WAITING": self._wait = False
elif data[0] == "LOGIN":
if data[1] == config.SOURCE_AUTH:
self._source = sock
self._sendOK(sock)
else:
self._sendClose(sock)
elif data[0] == "MOUNT":
if self._source == sock:
self._mount = data[1]
else:
self._sendClose(sock)
elif data[0] == "CLIENT":
self._sendMount(sock)
self._writers.append(sock)
def _sendCloseAll(self):
for sock in self._connections:
sock.send("CLOSE")
sock.close()
def _sendClose(self, sock):
sock.send("CLOSE")
sock.close()
def main(self):
while True:
rl, wl, xl = select.select(self._connections, self._writers, [], 0.2)
for sock in rl:
if sock == self._socket:
con, ip = sock.accept()
self._connections.append(con)
else:
data = sock.recv(config.BUFFER)
if data:
self.recv(sock, data)
else:
if sock in self._writers:
self._writers.remove(sock)
if sock in self._connections:
self._connections.remove(sock)
for sock in wl:
packet = self._getPacket()
if packet != None:
self._sendBufPacket(sock, packet)
def run(self):
self.main()
class writeThread(Thread):
def __init__(self):
self.running = False
def make(self, client):
self.client = client
self.running = True
def run(self):
host = (config.HOST, config.PORT+1)
sock = socket.socket()
sock.connect(host)
sock.send("CLIENT")
sock.send("MOUNT:mountpoint")
while self.running:
data = sock.recv(config.BUFFER)
if data:
data = data.split(":", 1)
if data[0] == "buffer":
self.client.send(data[1])
elif data[0] == "CLOSE":
self.client.close()
break
if __name__=="__main__":
source = Source()
source.start()
webserver = WebServer()
webserver.runloop()
if I need to build the webserver part I will. But, I'll explain it.
Okay, so basically when someone connects to the websever under the mountpoint that was set, They will get there own personal thread that then grabs the data from Source() and sends it to them. Now say another person connects to the mount point and the last client as well as the source is still going. Wouldn't the new client be blocked from getting the Source data considering there are two active threads?
Your understanding of how Threads work in Python seems to be incorrect, based on the question you are asking. If used correctly, threads will not be blocking: you can instantiate multiple thread with Python. The limitation is that, due to the Global Interpreter Lock (GIL), you cannot get the full parallelism expected in thread programming (e.g. simultaneous execution and thus, reduced runtime).
What is going to happen in your case is that the two threads will take, together, the same amount of time that they would take if they were executed sequentially (although that is not necessarily what happens in practice).
Okay, I have copy and pasted some Python3 code that I have already written for a project that I am currently working on. With modification, you can make this code serve your purposes.
The code uses multiprocessing and multithreading. For my purposes, I am using multiprocessing so that sockets will run on one processor, and I can run a GUI program on another processor. You can remove the multiprocessor part if you prefer. The code below runs a socket message server. The server will listen for clients one at a time. Once a client has connected, a new thread will be initiated to handle all the communications between the server and each client. The server will then continue to search for for clients. At the moment however, the server only listens to data being sent from each client, and then it prints it to the terminal. With a small amount of effort, you can modify my code to send information from the server to each client individually.
import multiprocessing
import threading
from threading import Thread
class ThreadedServer(object):
def __init__(self, host, port):
self.host = host
self.port = port
self.sock = socket(AF_INET, SOCK_STREAM)
self.sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
self.sock.bind((self.host, self.port))
def listen(self):
self.sock.listen(3) #Allow 3 Clients to connect to this server
while True:
#The program will search for one client at a time
print("Searching for Client")
client, address = self.sock.accept()
print(address, " is connected")
#client.settimeout(60)
#Once a client has been found, start a individual client thread
d = threading.Thread(target = self.listenToClient, args=(client, address))
d.daemon = True
d.start()
def listenToClient(self, client, address):
size = 1024
while True:
try:
data = client.recv(size)
if not data:
break
if data:
print(data)
#client.send(response)
else:
raise error('Client disconnected')
except:
client.close()
return False
def dataSharingHost():
#Using Sockets to send information between Processes
#This is the server Function
#ThreadServer(Host_IP, Port_Number), for LocalHost use ''
ThreadedServer('', 8000).listen()
def Main():
commServer = multiprocessing.Process(target=dataSharingHost, args=())
commServer.daemon = True
commServer.start()
if __name__== '__main__':
Main()
And to be fair, my code is modified from https://www.youtube.com/watch?v=qELZAi4yra8 . The client code is covered in those videos. I think the 3rd video covers the multiple client connects.

How can I stop udp server in threading?

I wrote a udp no echo server in my program, I used thread to running and listen some message send by others. But it seems I couldn't stop it use tl.stop(), when I input q or quit. Some of my code is following:
class treadListen(threading.Thread):
def __init__(self):
self.running = True
threading.Thread.__init__(self)
def run(self):
address = ('localhost', 16666)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(address)
while True:
data = sock.recv(65535)
print "MESSAGE:{0}".format(data)
sock.close()
def stop(self):
self.running = False
# end of class thread_clock
if __name__ == "__main__":
tl = treadListen()
tl.start()
while True:
message = raw_input("CMD>")
if not message:
print "Please input command!"
continue
elif (message == 'quit') or (message == 'q'):
tl.stop()
break
else:
print "input is {0}".format(message)
# do something
continue
print "[CONNECTION CLOSED!]"
I was trying to add sock.shutdown(socket.SHUT_RDWR) and sock.close() to def stop of class, but it doesn't work.
How can I stop the thread safety? Thanks!
Your while loop while True: works forever, so I guess your close or shutdown calls to the socket never can gets in way to work.
You should change while True: to while self.running: and that should do the trick.
Thanks ntki,rbp,st.
The problem solved use following code:
class treadListen(threading.Thread):
def __init__(self):
**self.running = True**
threading.Thread.__init__(self)
def run(self):
address = ('localhost', 16666)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
**sock.settimeout(1)**
sock.bind(address)
**while self.running:
try:
data = sock.recv(65535)
print "MESSAGE:{0}".format(data)
except Exception, e:
continue**
sock.close()
def stop(self):
**self.running = False**
# end of class thread_clock

Python SocketServer.TCPServer errno 10054

I'm running a python server using the socketserver module in python 2.7. OmniPeek packet analysis tool shows the TCP handshake completes,
but the server immediately sends a reset packet killing the connection.
Simplified server code which shows the problem is:
from threading import Lock, Thread, Condition
import SocketServer
import socket
import sys
import time
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
def __init__(self, state, *args, **keys):
try:
state['lock'].acquire()
state['client_count'] += 1
finally:
state['lock'].release()
self.state = state
SocketServer.BaseRequestHandler.__init__(self, *args, **keys)
def handle(self):
self.state['lock'].acquire()
count = self.state['client_count']
self.state['lock'].release()
while True:
try:
self.state['lock'].acquire()
running = self.state['running']
self.state['lock'].release()
if not running:
break;
time.sleep(1) # do some work
except Exception as msg:
print msg
print "ThreadedTCPRequestHandler shutting down..."
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
def handler_factory(state):
def createHandler(*args, **keys):
return ThreadedTCPRequestHandler(state, *args, **keys)
return createHandler
if __name__ == "__main__":
lock = Lock()
cv = Condition(lock)
state = {'running': True, 'client_count': 0, 'lock': lock, 'cv': cv}
server = ThreadedTCPServer(('localhost', 12345), handler_factory(state))
server_thread = Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()
print "Server loop running in thread:", server_thread.name
# wait for a client to connect
cv.acquire()
while state['client_count'] == 0 and state['running']:
cv.wait(1.0)
# print msg
cv.release()
# substitute real work here...
time.sleep(5)
lock.acquire()
state['running'] = False
lock.release()
server.shutdown()
and the client code:
import socket
if __name__ == "__main__":
try:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'ip: {} port {}'.format('10.4.2.54', 12345)
client.connect(('10.4.2.54', 12345))
while True:
data = client.recv(4096)
if len(data) == 0:
break;
print 'data: {}'.format(data)
client.shutdown(socket.SHUT_RDWR)
client.close()
except Exception as msg:
print msg
The server code is based off python 2.7 docs serversocket Mixin example, and seems pretty straightforward, but...
Thanks
not sure what your expected behaviour is but if you make a couple of changes, you'll be able to see that it can work
replace your handle method
def handle(self):
while True:
try:
data = self.request.recv(1024).strip()
if len(data) != 0:
print data
time.sleep(1) # do some work
self.request.send('test data')
except Exception as msg:
print msg
break
print "ThreadedTCPRequestHandler shutting down..."
and client(inside main):
try:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'ip: {} port {}'.format('localhost', 1232)
client.connect(('localhost', 1232))
client.send('test')
n = 0
while True:
data = client.recv(4096)
if len(data) != 0:
print 'data: {}'.format(data)
time.sleep(1)
n += 1
client.send('keep-alive' + str(n) + '\n')
print 'here'
client.shutdown(socket.SHUT_RDWR)
client.close()
except Exception as msg:
print msg
I just modded it to send stuff and print stuff. But it doesn't crash.
I think there is an issue with your self.state['lock'].acquire() and release() calls. I took out the 'running' check as it's not really used except at the end of the server code.
Also, without any action, sockets will time out.
Once again, I'm not claiming to have 'fixed' your problem...and I'm not sure exactly what you are looking for...just helping you brainstorm!
Apologies - red herring. The problem is only occurring under VM when server is running under guest and client is running under host. TCP reset packet never sent when both client and server are running either on host or guest

Categories

Resources