On Saturday, May 4, 2013 5:37:42 AM UTC-4, Irmen de Jong wrote:
> On 4-5-2013 4:13, Pedro wrote: > SERVER: > > import socket # Import socket 
> module > > s = socket.socket() # Create a socket object > host = 
> socket.gethostname() # Get local machine name > port = 12345 # Reserve a port 
> for your service. > s.bind((host, port)) # Bind to the port This won't always 
> work as expected, particularly on machines with multiple network interfaces. 
> Depending on what your situation requires, a simpler s.bind(('', port)) can 
> be more suitable. (empty string means INADDR_ANY) > > s.listen(5) # Now wait 
> for client connection. > while True: > c, addr = s.accept() # Establish 
> connection with client. > print 'Got connection from', addr > c.send('Thank 
> you for connecting') The send() call returns the number of bytes actually 
> sent. This number can be LESS than the length of the buffer you wanted to 
> send! So you will need a loop here to make sure all data is actually 
> transmitted. The easiest way out is to use this instead: c.sendall('Thank you 
> for connecting') However, t
 his might fail due to some I/O error and then it leaves your socket in an 
undetermined state because you can't tell how much of the data was actually 
transmitted. (Recovering from errors is problematic if not impossible with 
sendall, as far as I know the only thing you can do is just close the bad 
socket and create a new one) > c.close() # Close the connection > > CLIENT: > 
import socket # Import socket module > > s = socket.socket() # Create a socket 
object > host = socket.gethostname() # Get local machine name > port = 12345 # 
Reserve a port for your service. > > s.connect((host, port)) > print 
s.recv(1024) While this usually seems to work (especially with small buffer 
sizes) it has the same problem as pointed out above with send(): recv() might 
not retrieve all data at once. It returns the amount of data actually received 
in that call. [warning, hairy details below] You HAVE to make a loop here to 
get all chunks of data until they add up to the total data size that you 
expected. 
 (There's a flag MSG_WAITALL you can pass to recv to get around this. But it is 
not available on all systems, and on some systems where it is provided, it 
doesn't work correctly.) Also you need to be careful with the buffer size 
passed to recv, too large and it causes problems on some systems. Around 60kb 
seems a good upper bound here. This usually also means you need to somehow tell 
the receiving end of the socket how much data is to be expected, and only then 
send that actual data. One way to do this is to send the length first as a 
struct-packed integer (4 bytes), and the data after that. Note that even 
reading the 4 bytes on the receiving side to determine the expected length 
might be broken up in multiple chunks: you can't even expect recv(4) to always 
return those 4 bytes. So even that needs to be in a loop... Other ways to know 
on the receiving end when to stop reading from the socket is to standardize on 
some sort of termination character (such as '\0' or perhaps '\n'), fixed
  length buffers, or to always close the socket after every single message (but 
that is hugely inefficient if you need to send multiple messages). > s.close # 
Close the socket when done > Oh, you forgot the parentheses here: s.close() 
Bottom line: Socket programming on this level is hugely complicated. It doesn't 
seem too bad if you start of with these simple example programs, but that's 
false hope. If at all possible, avoid direct socket programming, and use a 
high-level protocol or library instead (ftp/http/some IPC library/Twisted). Let 
them deal with the complexity of the socket layer. Regards Irmen de Jong

Thanks for the reply. I'm sending short strings as commands to my server 
machine so the socket module seems to be doing the trick reliably. I'll try to 
add Twisted to my arsenal though. 
Cheers
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to