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
Related
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.
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.
I have this script:
import threading, socket
for x in range(800)
send().start()
class send(threading.Thread):
def run(self):
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("www.google.it", 80))
s.send ("test")
print ("Request sent!")
except:
pass
And at the place of "Request sent!" I would like to print something like: "Request sent! %s" % (the current number of the thread sending the request)
What's the fastest way to do it?
--SOLVED--
import threading, socket
for x in range(800)
send(x+1).start()
class send(threading.Thread):
def __init__(self, counter):
threading.Thread.__init__(self)
self.counter = counter
def run(self):
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("www.google.it", 80))
s.send ("test")
print ("Request sent! #", self.counter)
except:
pass
Just a side answer to how to get the thread ID of the current thread (might not respond directly to the question but help others):
In python 3.3+ you can do simply :
import threading
threading.get_ident()
Read more : here
You could pass your counting number (x, in this case), as a variable in your send class. Keep in mind though that x will start at 0, not 1.
for x in range(800)
send(x+1).start()
class send(threading.Thread):
def __init__(self, count):
self.count = count
def run(self):
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("www.google.it", 80))
s.send ("test")
print ("Request sent!"), self.count
except:
pass
Or, as Rob commented above in the other question, threading.current_thread() looks satisfactory.
The easiest way to do this is to use setName and getName to give names to your threads.
import threading, socket
for x in range(800)
new_thread = send()
new_thread.setName("thread number %d" % x)
new_thread.start()
class send(threading.Thread):
def run(self):
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("www.google.it", 80))
s.send ("test")
print ("Request sent by %s!" % self.getName())
except:
pass
You can also add any other attributes to send that you need to keep track of your threads.
I am trying to run a function in the background, whilst continuing with said code in python.
The function I want to run in the background is from socket. Looking for specific data to cut the program off.
Here is the function:
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
Here is the code I want to run:
while True:
r = receive()
if r == "stop":
break
#Cannot get past here, because of the function running.
#Should loop over and over, until stop data is received
print "Running program"
I have tried threading, with r = threading.Thread(target=receive()) with no joy.
Rookie error:
r = threading.Thread(target=receive())
I did not take the brackets off the receive():
r = threading.Thread(target=receive)
You can't return to the invoking thread from an invoked thread's target function. Instead, you need some inter-thread communication system. Below, is an example using Python's Queue to pass received datagrams between the two threads. I've used a threading.Event to signal when the receiver thread should stop.
#!/usr/bin/env python
import socket
import threading
from queue import Empty, Queue
class DatagramReceiver(threading.Thread):
def __init__(self, stop, queue):
super().__init__()
self._stop = stop
self._queue = queue
def run(self):
with socket.socket(AF_INET, SOCK_DGRAM) as sock:
sock.bind(('', 13000))
while not self._stop.is_set():
data = sock.recvfrom(1024)[0]
if data == 'stop':
self._stop.set()
break
self._queue.put(data)
def main():
stop = threading.Event()
queue = Queue()
reader = DatagramReceiver(stop, queue)
reader.deamon = True
reader.start()
while not stop.is_set():
user_input = input('Press RETURN to print datagrams, or q quit')
if user_input == 'q':
break
while True:
try:
datagram = queue.get_nowait()
except Empty:
break
print(datagram)
stop.set()
reader.join()
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