Sockets

Joseph A Knapka jknapka at earthlink.net
Thu Oct 11 12:28:25 EDT 2001


Hugo Martires wrote:
> 
> #!/usr/bin/env python
> 
> from socket import *
> 
> HOST = 'localhost'
> PORT = 21567
> BUFSIZ = 1024
> ADDR = (HOST, PORT)
> 
> CliSock = socket(AF_INET, SOCK_STREAM)
> CliSock.connect(ADDR)
> 
> while(1):
>         data = CliSock.recv(BUFSIZ)
>         if not data: break
>         ???????????????????
> 
> CliSock.close()
> 
> ******************************
> My problem is : what i put in ???????????????
> Some people told me to use a delimeter betwen the 2 strings.
> But how can i use it? How to decode the whole string ?

There are a couple of approaches you could take. The
first would be to use a delimiter, and continue to
read until you see the delimiter, saving any additional
data for further reads:

delim = '!'

# Sender:
the_data = "xyzzy"
sock.send(the_data+delim)

# Receiver:
readbuf = ''

def get_item():
	""" Read and strip the first data item in readbuf. """
	val = ''
	if delim in readbuf:
		val = readbuf[:readbuf.index(delim)]
		readbuf = [readbuf.index(delim):]

def read_item():
	# Maybe we read multiple items in previous read_item():
	if delim in readbuf:
		return get_item()

	# Nope. Read new data.
	while(1):
	        data = CliSock.recv(BUFSIZ)
		readbuf = readbuf + data
		if delim in readbuf:
			return get_item(readbuf)


Another approach would be to read one character at
a time until you see your delimiter. Not as efficient,
but simpler to implement.

Finally, you could encode the length of the data in
a fixed-width field at the beginning of each data
item:

# Sender:
the_data = "xyzzy"
the_len = "%2d"%len(the_data)
sock.send(the_len)
sock.send(the_data)

# Receiver:
# We -know- we'll get two bytes of length:
the_len = int(sock.recv(2))
the_data = sock.recv(the_len)

This looks simpler, but you must code your sender
and receiver very carefully to avoid them getting
out-of-sync with respect to the location of the
length data, and/or provide re-synchronization
logic. The solution with delimiters doesn't
have that concern. On the other hand, if you use
the delimiter solution you must take care that
the delimiter does not appear within the data.
That's normally handled either by choosing data
representations that don't contain the delimiter
(eg, printable ASCII data, delimiter == 0x00),
or by a transparency scheme (replace all occurrences
of the delimiter in the data stream with a character
sequence that doesn't contain the delimiter).

HTH,

-- Joe
# "You know how many remote castles there are along the
#  gorges? You can't MOVE for remote castles!" - Lu Tze re. Uberwald
# Linux MM docs:
http://home.earthlink.net/~jknapka/linux-mm/vmoutline.html



More information about the Python-list mailing list