Plz help..SocketServer UDP server losing lots of packets

I

id.engg

logFileName = 'log.txt'
logfile = open(logFileName, "a")
class MyUDPServer(SocketServer.UDPServer):
def server_bind(self):
self.socket.setsockopt(socket.SOL_SOCKET,
socket.SO_RCVBUF, 8388608)
self.socket.bind(self.server_address)

class LogsDumpHandler(SocketServer.DatagramRequestHandler):
def handle(self):
global logfile
# fileExists is a function which checks the existence of a file
if not fileExists(logFileName):
logfile = open(logFileName, "a")
logfile.writelines(self.rfile.readlines())

server = MyUDPServer(("",PORT), LogsDumpHandler)
server.serve_forever()
logfile.close()

The above python code is a UDP server based on SocketServer framework
and I am losing a lot of messages, I have tried almost everything,
increasing the size of the receive buffer, changing the way i read the
messages coming into server.
The above code is supposed to work as a tracing server and it does but
is losing messages.
Is there a way I can improve this code?
Any help will be highly appreciated.

Thanks,
Sam
 
J

James Mills

logFileName = 'log.txt'
logfile = open(logFileName, "a")
class MyUDPServer(SocketServer.UDPServer):
def server_bind(self):
self.socket.setsockopt(socket.SOL_SOCKET,
socket.SO_RCVBUF, 8388608)
self.socket.bind(self.server_address)

class LogsDumpHandler(SocketServer.DatagramRequestHandler):
def handle(self):
global logfile
# fileExists is a function which checks the existence of a file
if not fileExists(logFileName):
logfile = open(logFileName, "a")
logfile.writelines(self.rfile.readlines())

server = MyUDPServer(("",PORT), LogsDumpHandler)
server.serve_forever()
logfile.close()

This is horrible code :/

Try these instead:
* UDPServer ->
http://trac.softcircuit.com.au/circuits/browser/examples/udpserver.py
* UDPClient ->
http://trac.softcircuit.com.au/circuits/browser/examples/udpclient.py

Example usage
----------------------

~/circuits/examples
$ ./udpserver.py
127.0.0.1, 9000:
test
127.0.0.1, 9000:
hi

~/circuits/examples
$ ./udpclient.py -b 127.0.0.1:9000 127.0.0.1:8000
test
127.0.0.1, 8000:
test
hi
127.0.0.1, 8000:
hi

You can download circuits from http://trac.softcircuit.com.au/circuits/
or get the latest development version by using Mercurial (1):
hg clone http://hg.softcircuit.com.au/projects/circuits/

cheers
James

[1] http://www.selenic.com/mercurial/wiki/
 
J

James Mills

Thanks for your response.
But I cannot use a third party software, I need to use the exisiting API's
within python.

Why ?
Even this seems to lose packets, I would really appreciate if any pointers
can be provided to improve my code.

You do realize that UDP is the User Datagram
Protocol and has no Control mechanisms.
You _cannot_ guarantee that packets will
arrive in the right order, if at all.

In all my tests however on local machines
and across machines in a LAN, I don't
loose packets. I do recommend you use
circuits (or twisted).

--JamesMills
 
B

Ben Sizer


Since there's no contact details on the Circuits site, and the guest
Trac account doesn't work (it asks the admin to verify the email),
then I'll post here: it appears that the Hello World example is wrong,
trying to add an instance of a 'hello' object that doesn't exist. I've
not tried to run the example, but it certainly confused me when trying
to work out how Circuits works.
 
S

Steve Holden

I said:
Hello James,
Thanks for your response.
But I cannot use a third party software, I need to use the exisiting
API's within python.
As I am new to python, I suspected that I should go by a simpler
approach and so
scrapped off the below code and wrote a very simple UDP server code as
follows:

logFileName = '/home/msat/gsc/logs/' + compNum + '/logparsertracedump.log'
logfile = open(logFileName, "w")
from socket import *
host = "121.3.0.1 <http://121.3.0.1>"
port = PORT
buf = 4096
addr = (host,port)
# Create socket and bind to address
UDPSock = socket(AF_INET,SOCK_DGRAM)
UDPSock.setsockopt(SOL_SOCKET, SO_RCVBUF, 8388608)
UDPSock.bind(addr)
while 1:
data,addr = UDPSock.recvfrom(buf)
if not fileExists(logFileName):
logfile = open(logFileName, "a")
logfile.writelines(data)

It would make more sense to leave the file open outside the loop. If
it's important to have each packet individually logged you can call the
file's .flush() method after each .writelines() call. No need to
continually re-open it. I doubt this is the source of your packet loss,
however. Maybe there's a bug in fileExists (for which you could have
used os.path.exists, by the way).
# Close socket
UDPSock.close()
How do you anticipate this line will ever be executed?

Your network code looks basically OK, though a little horrible with
things like 8388608 for the socket options. See if you get any ideas from

http://holdenweb.com/docs/NetProg.pdf

though it doesn't tell you much you don't appear to know already.

regards
Steve
Even this seems to lose packets, I would really appreciate if any
pointers can be provided to improve my code.

Thanks,
Sam

On Wed, Nov 5, 2008 at 7:46 PM, James Mills

logFileName = 'log.txt'
logfile = open(logFileName, "a")
class MyUDPServer(SocketServer.UDPServer):
def server_bind(self):
self.socket.setsockopt(socket.SOL_SOCKET,
socket.SO_RCVBUF, 8388608)
self.socket.bind(self.server_address)

class LogsDumpHandler(SocketServer.DatagramRequestHandler):
def handle(self):
global logfile
# fileExists is a function which checks the existence of a file
if not fileExists(logFileName):
logfile = open(logFileName, "a")
logfile.writelines(self.rfile.readlines())

server = MyUDPServer(("",PORT), LogsDumpHandler)
server.serve_forever()
logfile.close()

This is horrible code :/

Try these instead:
* UDPServer ->
http://trac.softcircuit.com.au/circuits/browser/examples/udpserver.py
* UDPClient ->
http://trac.softcircuit.com.au/circuits/browser/examples/udpclient.py

Example usage
----------------------

~/circuits/examples
$ ./udpserver.py
127.0.0.1 <http://127.0.0.1/>, 9000:
test
127.0.0.1 <http://127.0.0.1/>, 9000:
hi

~/circuits/examples
$ ./udpclient.py -b 127.0.0.1:9000 <http://127.0.0.1:9000/>
127.0.0.1:8000 <http://127.0.0.1:8000/>
test
127.0.0.1 <http://127.0.0.1/>, 8000:
test
hi
127.0.0.1 <http://127.0.0.1/>, 8000:
hi

You can download circuits from http://trac.softcircuit.com.au/circuits/
or get the latest development version by using Mercurial (1):
hg clone http://hg.softcircuit.com.au/projects/circuits/

cheers
James

[1] http://www.selenic.com/mercurial/wiki/
 
J

James Mills

Since there's no contact details on the Circuits site, and the guest
Trac account doesn't work (it asks the admin to verify the email),
then I'll post here: it appears that the Hello World example is wrong,
trying to add an instance of a 'hello' object that doesn't exist. I've
not tried to run the example, but it certainly confused me when trying
to work out how Circuits works.

Ben, thanks for your feedback! I've fixed this
now! I've also added come contact details for
myself on the website and fixed the guest
account! Thanks for taking an interest.

--JamesMills
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top