Reputation: 2279
I am struggling to get my python socket to behave.
There are two major problems:
1) When it listens for the client connection the program stalls which is a problem because it is running on a IRC client python interpreter causing the IRC client not to respond until the client connects.
2) When the client disconnects the entire script has to be stopped and then restarted again inorder to get the socket server to listen once more.
I thought the way around it might be to start the socket listening in a separate thread, so the IRC client can continue while it waits for the client connection. Also, once the client has decided to close the connection I need a way restart it.
The following code is terrible and doesn't work but it might give you an idea as to what I'm attempting:
__module_name__ = "Forward Module"
__module_version__ = "1.0.0"
__module_description__ = "Forward To Flash Module by Xcom"
# Echo client program
import socket
import sys
import xchat
import thread
import time
HOST = None # Symbolic name meaning all available interfaces
PORT = 7001 # Arbitrary non-privileged port
s = None
socketIsOpen = False
def openSocket():
# start server
print "starting to listen"
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
af, socktype, proto, canonname, sa = res
try:
s = socket.socket(af, socktype, proto)
except socket.error as msg:
s = None
continue
try:
s.bind(sa)
s.listen(1)
except socket.error as msg:
s.close()
s = None
continue
break
if s is None:
print 'could not open socket'
global socketIsOpen = False
sys.exit(1)
conn, addr = s.accept()
print 'Connected by', addr
global socketIsOpen = True
def someone_said(word, word_eol, userdata):
username = str(word[0])
message = str(word[1])
sendMessage = username + " : " + message
send_to_server(sendMessage)
def send_to_server(message):
conn.send(message)
def close_connection():
conn.close()
print "connection closed"
xchat.hook_print('Channel Message' , someone_said)
def threadMethod(arg) :
while 1:
if (not socketIsOpen) :
openSocket()
try:
thread.start_new_thread(threadMethod, args = [])
except:
print "Error: unable to start thread"
The python is running on an IRC client called HexChat which is where the xchat import comes from.
Upvotes: 2
Views: 2166
Reputation: 69032
The way you usually program a threaded socket server is:
accept()
in a loopA very minimal example would be somethig like this:
import socket
import threading
import time
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('0.0.0.0', 9999))
server.listen(1)
def handle(conn):
conn.send(b'hello')
time.sleep(1) # do some "heavy" work
conn.close()
while True:
print('listening...')
conn, addr = server.accept()
print('handling connection from %s' % (addr,))
threading.Thread(target=handle, args=(conn,)).start()
You're spawning new threads in which you create your listening socket, then accept and handle your connection. And while socketIsOpen
is True
your programm will be using a lot of cpu looping through your while loop doing nothing. (btw, the way you check socketIsOpen
allows for race conditions, you can start multiple threads before it is set.)
And one last thing, you should try to use the threading
module instead of the deprecated thread
.
Upvotes: 1