socket([family[, type[, proto]]]) -> socket object Open a socket of the given type. The family argument specifies the address family; it defaults to AF_INET. The type argument specifies whether this is a stream (SOCK_STREAM, this is the default) or datagram (SOCK_DGRAM) socket. The protocol argument defaults to 0, specifying the default protocol. Keyword arguments are accepted. A socket object represents one endpoint of a network connection. Methods of socket objects (keyword arguments not allowed): accept() -- accept a connection, returning new socket and client address bind(addr) -- bind the socket to a local address close() -- close the socket connect(addr) -- connect the socket to a remote address connect_ex(addr) -- connect, return an error code instead of an exception dup() -- return a new socket object identical to the current one [*] fileno() -- return underlying file descriptor getpeername() -- return remote address [*] getsockname() -- return local address getsockopt(level, optname[, buflen]) -- get socket options gettimeout() -- return timeout or None listen(n) -- start listening for incoming connections makefile([mode, [bufsize]]) -- return a file object for the socket [*] recv(buflen[, flags]) -- receive data recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer) recvfrom(buflen[, flags]) -- receive data and sender's address recvfrom_into(buffer[, nbytes, [, flags]) -- receive data and sender's address (into a buffer) sendall(data[, flags]) -- send all data send(data[, flags]) -- send data, may not send all of it sendto(data[, flags], addr) -- send data to a given address setblocking(0 | 1) -- set or clear the blocking I/O flag setsockopt(level, optname, value) -- set socket options settimeout(None | float) -- set or clear the timeout shutdown(how) -- shut down traffic in one or both directions
In network programming, it is common to hear about different kinds of I/O programming models such as blocking I/O, nonblocking I/O, and polling. The purpose of this exercise is to simply define what these terms mean with some simple socket examples. (a) Blocking I/O Blocking I/O means that operations such as accept(), recv() or send() will block (wait) until the requested operation can be completed. Consider the server you were working on in the last exercise: >>> from socket import * >>> s = socket(AF_INET, SOCK_STREAM) >>> s.bind(("",15000)) >>> s.listen(5) >>> c,a = s.accept() You will notice that the accept() operation waits indefinitely until a new connection arrives. This is blocking I/O in action. In IDLE (client), connect to your server to see it unblock and return. >>> from socket import * >>> s = socket(AF_INET, SOCK_STREAM) >>> s.connect(("localhost",15000)) >>> (b) Blocking I/O with a timeout You can set a timeout using the settimeout() method of a socket. In your server, set a timeout on the client connection that you just received. Try to receive some data and just sit there and wait: >>> c.settimeout(15) >>> c.recv(8192) ... wait 15 seconds. See what happens ... In production code, setting some kind of timeout is probably not a bad idea. A common failure mode for servers is the case where a client connects, but then never sends any data--holding the client connection open forever. With a timeout, the server can give up after a while and close the connection. (c) Non-blocking I/O Non-blocking I/O is a style of I/O handling where operations immediately raise an exception if the operation can't be completely immediately. On the server, try doing this with the client connection received in part (b): >>> c.setblocking(False) >>> c.recv(8192) Traceback (most recent call last): File "", line 1, in socket.error: [Errno 35] Resource temporarily unavailable >>> You will notice that recv() immediately raises an exception. If you try it again, you'll get the same exception over and over. In IDLE (the client), try sending a short message to the server: >>> s.send("Hello?") 6 >>> Try redoing the recv() operation. Notice that it works now. This is because the server received some data that it can now return. >>> c.recv(8192) 'Hello?' >>> Although non-blocking I/O could be used to periodically check a socket for incoming data, it's extremely uncommon for it to be used in that manner. It is actually more common for non-blocking mode to be used when sending data. That might sound counterintuitive, but it allows the sender to continue with its data processing even if a socket's output buffers are temporarily full (instead of blocking, the sender continues to do other work).