Python Client hangs when no data to receive from server and hangs in that thread w/o letting client send?

I think you want to try and set the socket to non-blocking mode.

Up vote 0 down vote favorite share g+ share fb share tw.

I am trying to figure out how to get my client to send and receive data 'simultaneously' and am using threads. My problem is that, depending on the way I set it up, the way here it waits for data from the server in the recieveFromServer function which is in its own thread and cannot stop it when nothing will be sent. The other way it just waits for user input, and will send to the server and then I'd call the function recieveFromServer after the client sends a message to the server which doesn't allow for fluent communication, but cannot get it to alternate automatically.

How do I release the thread when the client has nothing to be sent, or there is no more to be received from the server. It would get to long if I tried to explain everything I have tried. :) Thanks.

The client: from socket import * from threading import * import thread import time from struct import pack,unpack from networklingo import * #from exception import * HOST = '192.168.0.105' PORT = 21567 BUFFSIZE = 1024 ADDR = (HOST,PORT) lock = thread. Allocate_lock() class TronClient: def __init__(self,control=None): self. TcpSock = socket(AF_INET,SOCK_STREAM) #self.tcpSock.

Settimeout(.2) self. RecvBuff = def connect(self): self.tcpSock. Connect(ADDR) self.

ClientUID = self.tcpSock. Recv(BUFFSIZE) print 'My clientUID is ', self. ClientUID t = Thread(target = self.receiveFromSrv()) t.

SetDaemon(1) t.start() print 'going to main loop' self.mainLoop() #t = Thread(target = self.mainLoop()) #t. SetName('mainLoop') #t. SetDaemon(1) #t.start() def receiveFromSrv(self): RECIEVING = 1 while RECIEVING: #print 'Attempting to retrieve more data' #lock.acquire() #print 'Lock Aquired in recieveFromSrv' #try: data = self.tcpSock.

Recv(BUFFSIZE) #except socket. Timeout,e: #print 'Error recieving data, ',e #continue #print data if not data: continue header = data:6 msgType,msgLength,clientID = unpack("hhh",header) print msgType print msgLength print clientID,'\n' msg = data6: while len(msg) ') except EOFError: # enter key hit without any data (blank line) so ignore and continue continue #if not data or data == '': # no valid data so just continue # continue if data=='exit': # client wants to disconnect, so send request to server self.disconnect() break else: self. Send(TRON_CHAT,data) #lock.release() #print 'lock released in main loop' #self.recieveFromSrv() #data = self.tcpSock.

Recv(BUFFSIZE) #t = Thread(target = self.receiveFromSrv()) #t. SetDaemon(1) #t.start() if __name__ == "__main__": cli = TronClient() cli.connect() #t = Thread(target = cli.connect()) #t. SetName('connect') #t.

SetDaemon(1) #t.start() The server (uses a lock when incrementing or decrementing number of clients): from socket import * from threading import * import thread from controller import * from networklingo import * from struct import pack,unpack HOST = '' PORT = 21567 BUFSIZE = 1024 ADDR = (HOST,PORT) nclntlock = thread. Allocate_lock() class TronServer: def __init__(self,maxConnect=4,control=None): self. ServSock = socket(AF_INET,SOCK_STREAM) # ensure that you can restart server quickly when it terminates self.servSock.

Setsockopt(SOL_SOCKET,SO_REUSEADDR,1) self.servSock. Bind(ADDR) self.servSock. Listen(maxConnect) # keep track of number of connected clients self.

ClientsConnected = 0 # give each client a unique identfier for this run of server self. ClientUID = 0 # list of all clients to cycle through for sending self. AllClients = {} # keep track of threads self.

CliThreads = {} #reference back to controller self. Controller = control self. RecvBuff = def removeClient(self,clientID,addr): if clientID in self.allClients.keys(): self.

AllClientsclientID.close() print "Disconnected from", addr nclntlock.acquire() self. ClientsConnected -= 1 nclntlock.release() del self. AllClientsclientID else: print 'ClientID is not valid' def recieve(self,clientsock,addr): RECIEVING = 1 # loop serving the new client while RECIEVING: # while PLAYING?

Try: data = clientsock. Recv(BUFSIZE) except: RECIEVING = 0 continue # if not data: break #no data was recieved if data! = '': print 'Recieved msg from client: ',data header = data:6 msgType,msgLength,clientID = unpack("hhh",header) print msgType print msgLength print clientID,'\n' if msgType == DISCONNECT_REQUEST: #handle disconnect request self.

RemoveClient(clientID,addr) else: #pass message type and message off to controller msg = data6: while len(msg) Sendall(data) self. Send(TRON_CHAT,msg,-1) #send to client 0 for k in self.allClients.keys(): if self. AllClientsk == clientsock: self.

RemoveClient(k,addr) print 'deleted after hard exit from clientID ', k #self.cliThreadsk.join() #del self. CliThreadsk # then tell controller to delete player with k break def send(self,msgType,msg,clientID=-1): header = pack("hhh",msgType,len(msg),clientID) msg = header+msg if clientID in self. AllClients: self.

AllClientsclientID. Send(msg) elif clientID==ALL_PLAYERS: for k in self.allClients.keys(): self.allClientsk. Send(msg) def mainLoop(self): global nclntlock try: while self.

Controller! = None and self.controller. State == WAITING: print 'awaiting connections' clientsock, caddy = self.servSock.accept() nclntlock.acquire() self.

ClientsConnected += 1 nclntlock.release() print 'Client ',self. ClientUID,' connected from:',caddy clientsock. Setblocking(0) clientsock.

Send(str(self. ClientUID)) self.allClientsself. ClientUID = clientsock t = Thread(target = self.

Recieve, args = clientsock,caddy) t. SetName('recieve-' + str(self. ClientUID)) self.cliThreadsself.

ClientUID = t self. ClientUID += 1 # t. SetDaemon(1) t.start() finally: self.servSock.close() if __name__ == "__main__": serv = TronServer(control = LocalController(nPlayers = 3, fWidth = 70, fHeight = 10)) t = Thread(target = serv.mainLoop()) t.

SetName('mainLoop') # t. SetDaemon(1) t.start() python server multithreading client locking link|improve this question asked Feb 13 '10 at 1:19Devin263.

I think you want to try and set the socket to non-blocking mode: docs.python.org/library/socket.html#sock... Set blocking or non-blocking mode of the socket: if flag is 0, the socket is set to non-blocking, else to blocking mode. Initially all sockets are in blocking mode. In non-blocking mode, if a recv() call doesn’t find any data, or if a send() call can’t immediately dispose of the data, a error exception is raised; in blocking mode, the calls block until they can proceed.

S. Setblocking(0) is equivalent to s. Settimeout(0); s.

Setblocking(1) is equivalent to s. Settimeout(None). Also, instead of using raw sockets, have you considdered using the multiprocessing module.

It is a higher-level abstraction for doing network IO. The section on Pipes & Queues is specific to sending and receiving data between a client/server.

Thank-you for the response. I have tried self.tcpSock. Setblocking(0) before the recv call, however seems to make no difference and kept it in the server code anyways (for now).

I've been taking a look at the multiprocessing module and do you happen to know if it would be easy to integrate that with what I already have as I am just learning python? I'm not exactly sure how I would use one of these approaches. Thanks in advance for the help.

– Devin Feb 13 '10 at 2:43.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions