The following code is giving a global name not defined error, but as far as I can see the name is defined. I'm new to Python, is this a scope issue?
import os, socket
from threading import Thread
class serv:
def __init__(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(('', 443))
def run(self):
self.socket.listen(10)
print "Listening"
self.conn, self.addr = self.socket.accept()
try:
Thread(target=clientThread, args=(self.conn,)).start()
except Exception, errtxt:
print errtxt
def exit(self):
print "Disconnected"
self.conn.close()
def clientThread(conn):
print "Connected"
while 1:
conn.send("Hello, worlds!\n")
S = serv()
S.run()
The specific error is
global name 'clientThread' is not defined
you should use
self.clientThread
I would make these changes:
(1) Pass self to self.clientThread
def run(self):
self.socket.listen(10)
print "Listening"
self.conn, self.addr = self.socket.accept()
try:
Thread(target=self.clientThread, args=(self,)).start()
except Exception, errtxt:
print errtxt
(2) Reference self in clientThread
def clientThread(self):
print "Connected"
while 1:
self.conn.send("Hello, worlds!\n")
Another possibility is to have your object derive from threading.Thread instead of have a Thread. Then your code looks more like this:
import os, socket
from threading import Thread
class serv(Thread):
def __init__(self):
super(serv, self).__init__()
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(('', 443))
def run(self):
self.socket.listen(10)
print "Listening"
self.conn, self.addr = self.socket.accept()
try:
print "Connected"
while 1:
self.conn.send("Hello, worlds!\n")
except Exception, errtxt:
print errtxt
def exit(self):
print "Disconnected"
self.conn.close()
S = serv()
S.start()
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 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 wanted to make a connection between a sever and a client, so the server sends a string to the client.
Here is the Server:
import socket
def Main():
host = '190.176.141.23'#ip changed
port = 12345
while True:
s = socket.socket()
s.bind((host,port))
s.listen(1)
c, addr = s.accept()
print "Connection from: " + str(addr)
command = c.recv(1024)
if command == 'GIVETEXT':
c.send('test')
try:
c.close()
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
except SocketError as e:
if e.errno != errno.ECONNRESET:
raise
pass
if __name__ == '__main__':
Main()
And here is the Client I made:
import socket
class Client(object):
def __init__(self, *args):
self.s = socket.socket()
def sent(self, host, port):
self.s.connect((host, port))
self.s.send('GIVETEXT')
self.Text = self.s.recv(1024)
print self.Text
self.s.close
return self.Text
Needless to say, that I executed the method in another piece of code, and it worked. But after that the server crashed, with the error message:
NameError: global name 'SocketError' is not defined
It is socket.error; not SocketError. Change your except line to:
except socket.error as e:
Please look at the following python code.
I created a Server class to listen on port 10000 to receive UDP broadcast messages.
If IP address is configured in the system, it can receive UDP broadcast messages. If no ip address configured, it cannot receive any messages.
Could you tell me why?
import socket
import sys
class Server:
class Handler:
def handle(self, message):
pass
def __init__(self, serialNo):
self.serialNo = serialNo
def _setAddress(self, socket, message, address):
self.message = message
self.address = address
self.socket = socket
def send(self, message):
self.socket.sendto(message, self.address)
def getSerialNo(self):
return self.serialNo
def __init__(self, port, handler):
self.ss = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.ss.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.ss.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
self.handler = handler
try:
self.ss.bind(('<broadcast>', port))
except:
self.ss.close()
raise RuntimeError("Create socket error")
self.ss.setblocking(1)
def loop(self):
while True:
try:
print "Listening for broadcast..."
message, address = self.ss.recvfrom(8192)
print "Got request from %s:%s" % (address, message)
self.handler._setAddress(self.ss, message, address)
self.handler.handle(message)
except (KeyboardInterrupt, SystemExit):
raise
except:
sys.exc_info()[0]
After referring to pydhcp client code, I made following changes:
import socket
import sys
import select
class Server:
class Handler:
def handle(self, message):
pass
def __init__(self, serialNo):
self.serialNo = serialNo
def _setAddress(self, socket, message, address):
self.message = message
self.address = address
self.socket = socket
def send(self, message):
self.socket.sendto(message, self.address)
def getSerialNo(self):
return self.serialNo
def __init__(self, port, handler):
self.ss = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.ss.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.ss.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
self.handler = handler
try:
self.ss.bind(("0.0.0.0", int(port)))
except:
self.ss.close()
raise RuntimeError("Create socket error")
def loop(self):
while True:
try:
print "Listening for broadcast..."
data_input,data_output,data_except = select.select([self.ss],[],[], 60)
if (data_input != []):
(message, address) = self.ss.recvfrom(2048)
print "Got request from %s:%s" % (address, message)
self.handler._setAddress(self.ss, message, address)
self.handler.handle(message)
else:
print "no data within 60 seconds"
except (KeyboardInterrupt, SystemExit):
raise
except:
sys.exc_info()[0]
Now it can receive the broadcasting packets, but it cannot work on RedHat.
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