source = "http://www.amk.ca/files/python/crypto/" + \
"pycrypto-2.0.1.tar.gz" target = source[source.rfind("/") + 1:] name, message = urllib.urlretrieve(source, target)
The name holds the name that the source was saved under; it will be the same as target in this case, but if no target is specified it will be a generated name—for example, /tmp/tmpX-R8z3.tar.gz. For an HTTP download, the message is an httplib.HTTPMessage instance that contains the relevant HTTP headers.
Python's urllib and urllib2 standard library modules are very versatile. They can use the FTP and HTTP protocols, in the latter case using GET or POST, and they can use an HTTP proxy. The urllib2 module supports basic authentication and can be used to set HTTP headers. And if Python has been installed with SSL support, the urllib2 module can use the HTTPS protocol. The standard library also includes support for many other network protocols, including IMAP4, POP3, and SMTP for email, and NNTP for network news, as well as libraries for handling cookies, XML-RPC, and CGI, and for creating servers. Most of Python's networking support is based on the socket module, which can be used directly for low-level network programming.
In addition to Python's standard library, PyQt4 provides its own set of networking classes, including QFtp for client-side FTP support and QHttp for HTTP support. Low-level networking can be done using QAbstractSocket subclasses, including QTcpSocket, QTcpServer, and QUdpSocket, and from Qt 4.3, QSslSocket.
The Python standard library has many modules that provide networking facilities. We saw one example of a standard library networking function back in Chapter 4, when we used urllib2.urlopen() to provide a "file handle" to a file on the Internet that we then read line by line using the for line in fh: idiom. It is also possible to just "grab" an entire file from the Internet:
Networking support for Python can also be found in other third-party libraries, the most well known being the Twisted networking framework; see http://twistedmatrix.com for further details.
In this chapter we will only concern ourselves with creating a simple client/ server application, and we will create both the client and the server using just two of PyQt's networking classes: QTcpSocket and QTcpServer. In the next chapter, we will look at a multithreaded version of the server that is capable of handling multiple simultaneous requests without having to block.
Client/server applications are normally implemented as two separate programs: a server that waits for and responds to requests, and one or more clients that send requests to the server and read back the server's response. For this to work, the clients must know where to connect to the server, that is, the server's IP address and port number. Also, both clients and server must send and receive data using an agreed-upon socket protocol, and using data formats that they both understand.
PyQt provides two different kinds of socket. The UDP (User Datagram Protocol) is supported by the QUdpSocket class. UDP is lightweight, but unreliable—there are no guarantees that data will be received. UDP is connectionless, so data is just sent or received as discrete items. The TCP (Transmission Control Protocol) is supported by the QTcpSocket class. TCP is a reliable connection- and stream-oriented protocol; any amount of data can be sent and received—the socket is responsible for breaking the data into chunks that are small enough to send, and for reconstructing the data at the other end.
UDP is often used to monitor instruments that give continuous readings, and where the odd missed reading is not significant. Client/server applications normally use TCP because they need reliability; this is the protocol we will use in this chapter.
Another decision that must be made is whether to send and receive data as lines of text, or as blocks of binary data. PyQt's TCP sockets can use either approach, but we have opted to work with binary data since this is the most versatile and easiest to handle.
The example we will use is the Building Services application. The server holds details of the rooms in a building and the dates they have been booked. The client is used to book and unbook particular rooms for particular dates. Any number of clients can be used, but if two clients make a request that arrives at exactly the same time, one will be blocked until the other's request has been handled. This problem can be mitigated by using a threaded server, as we will see in the next chapter.
For the sake of the example, we will run the server and clients on the same machine; this means that we can use "localhost" as the IP address. The server and two clients are shown in Figure 18.1. We have also chosen a port number of 9 407—this is just an arbitrary number. The port number should be greater than 1023 and is normally between 5001 and 32767, although port numbers
up to 65 535 are valid. The server can accept two kinds of request, "BOOK" and "UNBOOK", and can make three kinds of response, "BOOK", "UNBOOK", and "ERROR". All the requests and responses are sent and received as binary data; we will look at their formats in the sections that follow.
In addition to the port number that is held in the PORT variable, we also create the SIZEOF_UINT16 variable and set it to 2 (meaning two bytes). In addition to the normal imports, we must also import the QtNetwork module:
from PyQt4.QtNetwork import *
The same PORT and SIZEOF_UINT16 variables, and the same QtNetwork import, are used in both the client and the server applications. In the following section, we will look at the implementation of the client, and in the second section we will review the server.
Was this article helpful?
Download Tube Jacker And Discover Everything You Need To Know About Jacking Unlimited Traffic From The Video Giant. The drop dead easy way to create winning video campaigns that will FLOOD your website with unstoppable FREE traffic, all on complete and total autopilot. How to exploit a sneaky method of boosting exposure and getting your videos to the top of Google within 72 hours, guaranteed.