What's wrong with my simple HTTP socket based proxy script? - python

I wrote a simple Python script for a proxy functionality. It works fine, however, if the requested webpage has many other HTTP requests, e.g. Google maps, the page is rendered quite slow.
Any hints as to what might be the bottleneck in my code, and how I can improve?
#!/usr/bin/python
import socket,select,re
from threading import Thread
class ProxyServer():
def __init__(self, host, port):
self.host=host
self.port=port
self.sk1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def startServer(self):
self.sk1.bind((self.host,self.port))
self.sk1.listen(256)
print "proxy is ready for connections..."
while(1):
conn,clientAddr = self.sk1.accept()
# print "new request coming in from " + str(clientAddr)
handler = RequestHandler(conn)
handler.start()
class RequestHandler(Thread):
def __init__(self, sk1):
Thread.__init__(self)
self.clientSK = sk1
self.buffer = ''
self.header = {}
def run(self):
sk1 = self.clientSK
sk2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while 1:
self.buffer += sk1.recv(8192)
if self.buffer.find('\n') != -1:
break;
self.header = self.processHeader(self.buffer)
if len(self.header)>0: #header got processed
hostString = self.header['Host']
host=port=''
if hostString.__contains__(':'): # with port number
host,port = hostString.split(':')
else:
host,port = hostString,"80"
sk2.connect((host,int(port)))
else:
sk1.send('bad request')
sk1.close();
return
inputs=[sk1,sk2]
sk2.send(self.buffer)
#counter
count = 0
while 1:
count+=1
rl, wl, xl = select.select(inputs, [], [], 3)
if xl:
break
if rl:
for x in rl:
data = x.recv(8192)
if x is sk1:
output = sk2
else:
output = sk1
if data:
output.send(data)
count = 0
if count == 20:
break
sk1.close()
sk2.close()
def processHeader(self,header):
header = header.replace("\r\n","\n")
lines = header.split('\n')
result = {}
uLine = lines[0] # url line
if len(uLine) == 0: return result # if url line empty return empty dict
vl = uLine.split(' ')
result['method'] = vl[0]
result['url'] = vl[1]
result['protocol'] = vl[2]
for line in lines[1: - 1]:
if len(line)>3: # if line is not empty
exp = re.compile(': ')
nvp = exp.split(line, 1)
if(len(nvp)>1):
result[nvp[0]] = nvp[1]
return result
if __name__ == "__main__":
HOST, PORT = "0.0.0.0", 8088
proxy = ProxyServer(HOST,PORT)
proxy.startServer()

I'm not sure what your speed problems are, but here are some other nits I found to pick:
result['protocal'] = vl[2]
should be
result['protocol'] = vl[2]
This code is indented one level too deep:
sk2.connect((host,int(port)))
You can use this decorator to profile your individual methods by line.

Related

EOFError in converting string to list

I have a code which is running on 2 hosts. They are processing some photos. When host1 receives a message, it will send some of its photos to host2 for processing. It will also send a list to host2 (it will convert it to string and then it will send it).
import pickle
import time, threading
host = commands.getoutput("hostname -I")
port = 5005
i = 0
backlog = 5
BUFSIZE = 4096
queueList = []
start = []
end = []
l = threading.Lock()
def read_udp(s):
data,addr = s.recvfrom(1024)
global start
if data.startswith('10.0.0'):
print("received message:", data)
data_split = data.split(" ")
address = data_split[0]
num = int(data_split[1])
ipToTransfer = address
l.acquire()
transferList = queueList[-num:]
del queueList[-num:]
transferStart = start[-num:]
del start[-num:]
l.release()
msg = pickle.dumps(transferStart)
#udp_send('New Transfer', ipToTransfer)
udp_send(msg, ipToTransfer)
send_file(ipToTransfer, transferList)
else:
recvStart = pickle.loads(data)
print("start before add::: ", start)
print("received::: ", recvStart)
l.acquire()
start = start + recvStart
l.release()
print("start after add::: ", start)
def udp_send(s, ip):
UDP_IP = ip
if(type(s) == str):
MESSAGE = s
else:
MESSAGE = pickle.dumps(s)
#print(MESSAGE)
print ("UDP target IP & port:", UDP_IP, port)
print ("message:", MESSAGE)
sock3 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
sock3.sendto(MESSAGE, (UDP_IP, port))
class Receiver:
''' Buffer binary data from socket conn '''
def __init__(self, conn):
self.conn = conn
self.buff = bytearray()
def get(self, size):
''' Get size bytes from the buffer, reading
from conn when necessary
'''
while len(self.buff) < size:
data = self.conn.recv(BUFSIZE)
if not data:
break
self.buff.extend(data)
# Extract the desired bytes
result = self.buff[:size]
# and remove them from the buffer
del self.buff[:size]
return bytes(result)
def save(self, fname):
''' Save the remaining bytes to file fname '''
with open(fname, 'wb') as f:
if self.buff:
f.write(bytes(self.buff))
while True:
data = self.conn.recv(BUFSIZE)
if not data:
break
f.write(data)
def send(sock2, data2):
while data2:
sent = sock2.send(data2)
data2 = data2[sent:]
def send_file(ipToTransfer, transferList):
while transferList:
fname = transferList.pop(0)
print("transferring:", fname)
with open(fname, 'rb') as f:
sock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock2.connect((ipToTransfer, 5005))
except socket.error as err:
print(err, ipToTransfer, 5005)
sock2.close()
return
# Send the file name length & the filename itself in one packet
send(sock2, pack('B', len(fname)) + fname.encode())
while True:
data2 = f.read(BUFSIZE)
if not data2:
break
send(sock2, data2)
sock2.close()
When host2 receives this string, it will convert it to list again, but I receive an EOFError in this part. My cmd doesn't have the copy capability, so I upload the photo from this error:
What's wrong?
you delete the pointer to what is being pickled
transferStart = start[-num:]
del start[-num:]
l.release()
msg = pickle.dumps(transferStart)
If you are trying to remove elements from a list that is not the way to do it. Consider popping or reassigning into another list that does not have that element, etc.

is the logic behind my trivial tftp client flawed?

I'm still a student so I might have missed something really obvious.
So I am stressing out about this so much.
But anyway here's my TFTP python code, all it does is downloading a text-file from our lecturer's server.
The file generated by it looks like this:
http://pastebin.com/TP8hngxM
And the original file like this:
http://pastebin.com/xDMjkABp
And if you run it through a difference checker, the difference is miniscule and in only 1 specific spot and it's really difficult for me to figure out why is this happening.
The downloaded file has a few extra words.
If you have spare 5 minutes, could you please check out my nested while loop (everything else was provided by the lecturer and can't be changed) to see if there's anything wrong with it?
The worst thing is that I've already had it working, but I lost my memory stick and I lost the most up-to-date version of the program that was running 100% fine.
So as I said, it's only about the nested while loop, I' not allowed to change anything above it.
#!/usr/bin/python
import struct
import sys
import os
import select
import glamnetsim
from socket import *
serverHost = 'mcgreg.comp.glam.ac.uk'
serverPort = 69
timeoutSecs = 5
debugging = False
RRQ, WRQ, DATA, ACK, ERROR = range(1, 6)
codeDescriptions = {RRQ:"RRQ", WRQ:"WRQ", DATA:"DATA", ACK:"ACK", ERROR:"ERROR"}
def printf (format, *args):
print str(format) % args,
def finish ():
printf("you should see\n1e951df315d433aa4df2065a1ad31311\n")
os.system("md5sum newfile.txt")
sys.exit(0)
def sendPacket (packet, port):
global sock, debugging
global serverIp
if debugging:
for i in packet:
print ('%02x' % ord(i)),
print ''
sock.sendto(packet, (serverIp, port))
def sendReadRequest (filename, mode):
global serverPort
format = "!H%ds" % (len(filename)+1)
format += "%ds" % (len(mode)+1)
s = struct.pack(format, 1, filename, mode)
sendPacket(s, serverPort)
def sendRealAck(blockno, port):
s = struct.pack("!H", 4)
s += struct.pack("!H", blockno)
sendPacket(s, port)
def sendACK (blockno, port):
print " -> ACK:%d\n" % blockno
if blockno == 0:
sendReadRequest("the_machine_stops.txt", "octet")
else:
sendRealAck(blockno, port)
def stripPacket (s):
if len(s)>3:
code = struct.unpack("!H", s[:2])[0]
blockno = struct.unpack("!H", s[2:4])[0]
data = s[4:]
code, data = glamnetsim.simulatePossibleError (code, data)
return code,blockno,data
else:
debugPrint("corrupt packet")
return -1,-1,""
def debugPrint (s):
global debugging
if debugging:
print s
def getDesc (c):
global codeDescriptions
return codeDescriptions[c]
sock = socket(AF_INET, SOCK_DGRAM)
serverIp = gethostbyname(serverHost)
sock.setblocking(1)
sendReadRequest("the_machine_stops.txt", "netascii")
lastblock = 0
blockno = 0
port = serverPort
f = open("newfile.txt", "w")
while True:
while True:
if blockno == lastblock+1:
break
r, w, x = select.select([sock], [], [], 5.0)
if r == []:
sendACK(lastblock, port)
else:
(packet, (address, port)) = sock.recvfrom(512+4)
code, newblock, text = stripPacket(packet)
print code, blockno
if code is 3:
blockno = newblock
sendACK(blockno, port)
if code is 5:
sendACK(lastblock, port)
print "Bn: " + str(blockno) + " Lb: " + str(lastblock)
lastblock = blockno
f.write(text)
print "OK"
if len(text) < 512:
break
f.close()
finish()
f.write(text)
That line is run with a stale value if blockno == lastblock+1. It probably should be within the inner loop.

How can I make a proxy server with python?

I've been trying to make a proxy server that allows UA spoofing but, it doesn't seem to work and I don't know why.
config.py
# if you want to spoof the useragent then,
# replace "$MyAgent" with the desired agent.
# For example,
# agent="Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:44.0) Gecko/20100101 Firefox/44.0"
host="127.0.0.1"
port=8888
byte=4096
listeners=100
delay=00000.1
agent="$MyAgent"
Proxy.py
import socket, select, time, config, sys
def Print(val):
sys.stdin.flush()
sys.stdout.write(val)
class ProxyServer(object):
def __init__(self):
self._host = (config.host, config.port)
self._socket = socket.socket()
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._socket.setblocking(False)
self._agent = config.agent
self._bytes = config.byte
self._delay = config.delay
self._listeners = config.listeners
self._cons = list()
self._log = Print
def _bind(self):
self._socket.bind(self._host)
self._socket.listen(self._listeners)
def main(self):
self._cons.append(self._socket)
while True:
time.sleep(self._delay)
rl, xl, wl = select.select(self._cons, [], [])
for sock in rl:
if sock == self._socket:
sock, ip = self._socket.accept()
self._on_connect()
self._cons.append(sock)
elif sock == None:
self._socket.close()
data = sock.recv(self._bytes)
agent = self._get_agent_header(data)
if not agent == "NO_AGENT":
agent_new = self._agent.replace("$MyAgent", agent)
data = data.replace(agent, agent_new)
sock.send(data)
else:
sock.send(data)
if not data:
self._on_close(sock)
def _on_close(self, sock):
self._cons.remove(sock)
self._log("client dc {0} left".format(self._count()))
sock.close()
def _on_connect(self):
self._log("connection made, {0} clients connected".format(self._count()))
def _count(self):
c = len(self._cons) - 1
return c
def _get_agent_header(self, data):
pat = "User-Agent: (.+)"
m = re.search(pat, data)
if m:
return m.group(0)
else:
return "NO_AGENT"
if __name__ == '__main__':
server = ProxyServer()
server._bind()
server.main()
If you run this the request will not complete. But, some of the headers will show in plain text. Is there something I'm not doing right?

Python weird code error

I have an IRC bot and I'm trying to get information for game server (GTA SA Multiplayer).
I have ready-to-use query, but I can't implement it into my bot. It works if I try to load the same script, but without getting it into bot's structure. The error it gives me is
NameError: name 'ip' is not defined
I've tried adding the ip address as argument in def(inp,say=None), but it still didn't work. That's the code:
from util import Query
from util import hook
import sys
#hook.command
def serverinfo(inp,ip="",port="",say=None):
ip = "78.129.221.58"
port = 7777
if len(sys.argv) >= 3:
ip = str(sys.argv[1])
port = int(sys.argv[2])
query = Query(ip,port)
info = query.GetInformation()
say(info)
if info['players'] <= 100:
say(query.GetPlayers())
say(query.GetDetailedPlayers())
else: say('can\' get players because players is above 100')
say(query.Ping())
query.Close()
That's Query that I import:
import socket, struct, random, datetime
from cStringIO import StringIO
class Query:
def __init__(self, ip, port):
self.ip, self.port = socket.gethostbyname(ip), port
self.data = StringIO("")
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.connect((ip, port))
self.sock.settimeout(1)
def CreatePacket(self, opcode):
ips = self.ip.split('.');
packet = "SAMP{0}{1}{2}{3}{4}{5}{6}".format(chr(int(ips[0])), chr(int(ips[1])), chr(int(ips[2])), chr(int(ips[3])), chr(self.port & 0xFF), chr(self.port >> 8 & 0xFF), opcode)
if opcode == 'p':
packet += struct.pack("BBBB", random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
return packet
def GetInformation(self):
try:
self.sock.send(self.CreatePacket('i'))
info = {}
self.data = StringIO(self.sock.recv(2048))
self.data.read(11)
info['passworded'] = struct.unpack('?', self.data.read(1))[0]
info['players'] = struct.unpack('h', self.data.read(2))[0]
info['maxplayers'] = struct.unpack('h', self.data.read(2))[0]
info['hostname'] = self.data.read(struct.unpack('i', self.data.read(4))[0])
info['gamemode'] = self.data.read(struct.unpack('i', self.data.read(4))[0])
info['mapname'] = self.data.read(struct.unpack('i', self.data.read(4))[0])
except socket.timeout:
info['error'] = 1
return info
def GetRules(self):
try:
self.sock.send(self.CreatePacket('r'))
rules = {}
self.data = StringIO(self.sock.recv(2048))
self.data.read(11)
rulecount = struct.unpack('h', self.data.read(2))[0]
for i in range(rulecount):
name = self.data.read(struct.unpack('b', self.data.read(1))[0])
rules[name] = self.data.read(struct.unpack('b', self.data.read(1))[0])
except socket.timeout:
rules['error'] = 1
return rules
def GetPlayers(self):
try:
self.sock.send(self.CreatePacket('c'))
players = []
self.data = StringIO(self.sock.recv(2048))
self.data.read(11)
playercount = struct.unpack('h', self.data.read(2))[0]
for i in range(playercount):
name = self.data.read(struct.unpack('b', self.data.read(1))[0])
players.append([name, struct.unpack('i', self.data.read(4))[0]])
except socket.timeout:
players = {'error': 1}
return players
def GetDetailedPlayers(self):
try:
self.sock.send(self.CreatePacket('d'))
players = []
self.data = StringIO(self.sock.recv(2048))
self.data.read(11)
playercount = struct.unpack('h', self.data.read(2))[0]
for i in range(playercount):
playerid = struct.unpack('b', self.data.read(1))[0]
name = self.data.read(struct.unpack('b', self.data.read(1))[0])
score = struct.unpack('i', self.data.read(4))[0]
ping = struct.unpack('i', self.data.read(4))[0]
players.append([playerid, name, score, ping])
except socket.timeout:
players = {'error': 1}
return players
def Close(self):
self.sock.close()
def Ping(self):
packet = self.CreatePacket('p')
a = datetime.datetime.now()
self.sock.send(packet)
self.sock.recv(2048)
b = datetime.datetime.now()
c = b - a
return int((c.days * 24 * 60 * 60 + c.seconds) * 1000 + c.microseconds / 1000.0)
class Rcon:
def __init__(self, ip, port, password):
self.ip, self.port, self.password = socket.gethostbyname(ip), port, password
self.data = StringIO("")
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.connect((ip, port))
self.sock.settimeout(0.5)
def CreatePacket(self, opcode, password, command):
ips = self.ip.split('.');
packet = "SAMP{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}".format(chr(int(ips[0])), chr(int(ips[1])), chr(int(ips[2])), chr(int(ips[3])), chr(self.port & 0xFF), chr(self.port >> 8 & 0xFF), opcode, chr(len(password) & 0xFF), chr(len(password) >> 8 & 0xFF), password, chr(len(command) & 0xFF), chr(len(command) >> 8 & 0xFF), command)
return packet
def Send(self, command):
self.sock.send(self.CreatePacket('x', self.password, command))
output = []
while 1:
try:
self.data = StringIO(self.sock.recv(2048))
self.data.read(11)
strlen = struct.unpack('h', self.data.read(2))[0]
if strlen == 0: break
output += [self.data.read(strlen)]
except: break;
return output
def Close(self):
self.sock.close()
Any ideas?
Edit: After some changes I did, gives me the following error:
query = Query(ip,port)
TypeError: 'module' object is not callable
I've basically changed the location of ip and port, moved it out of the serverinfo command.
from util import Query
from util import hook
ip = "78.129.221.58"
port = 7777
query = Query(ip,port)
info = query.GetInformation()
#hook.command
def serverinfo(inp,ip="",port="",say=None):
say(info)
if info['players'] <= 100:
say(query.GetPlayers())
say(query.GetDetailedPlayers())
else: say('can\' get players because players are above 100')
say(query.Ping())
query.Close()
Try adding this to the start of the python code :
ip = "78.129.221.58"
port = 7777
Try
query = Query.Query(ip, port)
The problematic line is this one:
query = Query(ip,port)
If the initialization using the command line parameters fail or if you pass in insufficient arguments, ip will not be initialized resulting in the said error.
Also, a better way of testing out scripts is something like this:
def main():
if len(sys.argv) >= 3:
ip = str(sys.argv[1])
port = int(sys.argv[2])
query = Query(ip,port)
# start using query
else:
raise Exception("Insufficient args passed in")
if __name__ == '__main__':
main()
Raising an exception/error or printing out something guarantees that you know that insufficient args are passed in. Also, maybe move all that code out in the open to some function?

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

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 = data[6:]
while len(msg) < msgLength:
data = self.tcpSock.recv(BUFFSIZE)
dataLen = len(data)
if dataLen <= msgLength:
msg += data
else:
remLen = msgLength-len(data) #we just need to retrieve first bit of data to complete msg
msg += data[:remLen]
self.recvBuff.append(data[remLen:])
print msg
#else:
#lock.release()
# print 'lock release in receiveFromSrv'
#time.sleep(2)
#RECIEVING = 0
def disconnect(self,data=''):
self.send(DISCONNECT_REQUEST,data)
#self.tcpSock.close()
def send(self,msgType,msg):
header = pack("hhh",msgType,len(msg),self.clientUID)
msg = header+msg
self.tcpSock.send(msg)
def mainLoop(self):
while 1:
try:
#lock.acquire()
#print 'lock aquired in mainLoop'
data = raw_input('> ')
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.allClients[clientID].close()
print "Disconnected from", addr
nclntlock.acquire()
self.clientsConnected -= 1
nclntlock.release()
del self.allClients[clientID]
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 = data[6:]
while len(msg) < msgLength:
data = self.tcpSock.recv(BUFSIZE)
dataLen = len(data)
if dataLen <= msgLength:
msg += data
else:
remLen = msgLength-len(data) #we just need to retrieve first bit of data to complete msg
msg += data[:remLen]
self.recvBuff.append(data[remLen:])
print msg
# echo back the same data you just recieved
#clientsock.sendall(data)
self.send(TRON_CHAT,msg,-1) #send to client 0
for k in self.allClients.keys():
if self.allClients[k] == clientsock:
self.removeClient(k,addr)
print 'deleted after hard exit from clientID ', k
#self.cliThreads[k].join()
#del self.cliThreads[k]
# 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.allClients[clientID].send(msg)
elif clientID==ALL_PLAYERS:
for k in self.allClients.keys():
self.allClients[k].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.allClients[self.clientUID] = clientsock
t = Thread(target = self.recieve, args = [clientsock,caddy])
t.setName('recieve-' + str(self.clientUID))
self.cliThreads[self.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()
I think you want to try and set the socket to non-blocking mode:
http://docs.python.org/library/socket.html#socket.socket.setblocking
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.

Categories

Resources