Network programming for PyS60 (IX)

by Marcelo Barros

A new element was presented in our last post: exception handling. It is quite impossible to create a “bulletproof” programs without any kind of exception handling. In special, the PyS60 socket API does an extensive usage of exceptions to indicate errors like connection timeout, unexpected closed connections and so on. When programming, you need to create some exception handling for almost all socket functions.

For instance, see how to create a simple exception handling when connection to a server. For newer Python versions (1.9.x) you may use settimeout() socket method to limit the connection time. In fact, any socket operation will be timed out using this method. See this discussion at Forum Nokia.

import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
    s.connect(('nokia.com',2222))
except:
    print "Can´t connect"

Output (port 2222 does not have a server listening on it):

Can´t connect

But you can obtain more information about the error when using specific socket exceptions. For instance, take a look in the following example, where an exception raised for socket-related errors is used (socket.error):

import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
    s.connect(('nokia.com',2222))
except socket.error, e:
    print "ERROR: %s" % e

Output (much better then previous one, no?):

ERROR: timed out

Other useful exception is socket.gaierror, related to address resolution problems. In the next example an invalid address is used (nokiacom), generating an exception. And see how we can use several except statements.

import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
    s.connect(('nokiacom',2222))
except socket.gaierror, e:
    print "ADDR ERROR: %s" % e
except socket.error, e:
    print "ERROR: %s" % e

Output (more specific exception first):

ADDR ERROR: (11001, 'getaddrinfo failed')

Following the zen of Python statements “explicit is better than implicit” and “errors should never pass silently”, the last example is interesting since it handles all expected exceptions individually. However, the “lazy approach” (first example) may be enough in many situations.

Mono thread programs can be easily debugged with exceptions but multi thread programs are a little bit hard to debug. An additional technique is to use log files to debug. “Post-mortem analysis” are made simple with log files and no much effort is necessary to create your logging strategy.

A log class is suggested in the next code snippet. Just save it in a file called logfile.py and import the object FLOG. Any module may import this object and use it to add log messages with FLOG.add(msg). Caller information is automatically added to the log using the object sys._getframe and a semaphore (created with thread.allocate_lock) is provided to avoid reentrance problems when writing to the file.

# Fortune client - PyS60 network programming
# Marcelo Barros de Almeida
# marcelobarrosalmeida@gmail.com
 
import sys
import time
import thread
 
__all__ = [ "FLOG" ]
 
class FileLog(object):
    def __init__(self,filename):
        self.filename = filename
        self.file = open(self.filename,'at')
        self.lock = thread.allocate_lock()
 
    def add(self,msg):
        # collect caller information from stack call using _getframe
        caller = sys._getframe(1).f_code.co_name
        line = str(sys._getframe(1).f_code.co_firstlineno)
        # create log message
        timestamp = time.strftime("[%Y%m%d %H:%M:%S] ",time.localtime())
        logmsg = timestamp + caller + ":" + line + " - " + msg + " \n"
        # write log message, using a semaphore for controlling the file access
        self.lock.acquire()
        self.file.write(logmsg)
        self.file.flush()
        self.lock.release()
 
FLOG = FileLog("e:\\filelog.txt")

That´s all, folks ! See you in our next post.

Related posts:

  1. Network programming for PyS60 (VIII) Did you do your homework ? So, I would like...
  2. Network programming for PyS60 (XV) As discussed in post III, TCP sockets have flow...
  3. Network programming for PyS60 (VII) Everything is about “protocols” in computer networks, doesn’t it ?...
  4. Network programming for PyS60 (VI) Before presenting some server code it is important to discuss...
  5. Network programming for PyS60 (III) As I promised, today we will start with some programming,...

Related posts brought to you by Yet Another Related Posts Plugin.