|
YOUR FEEDBACK
|
TOP MICROSOFT .NET LINKS Protocols Exploring FTP in .NET 2.0
Microsoft's heart wasn't in it
Nov. 6, 2006 12:00 PM
Fall the network protocols missing from .NET 1.0 and 1.1, the most notable is the File Transfer Protocol (FTP). Manually implementing the protocol for software developers was an unreasonable expectation, especially considering the complexity of the protocol in comparison to such protocols as HTTP or TELNET. This led to a thriving third-party component industry that has been perfecting FTP implementations since VB3 (and has been an ideal example of the argument for buying versus building when FTP functionality was required, especially with a price point of around $250). With the coming of .NET 2.0, Microsoft has introduced a native FTP communications implementation, but with some very curious design decisions that may complicate programming sufficiently so as to make abandoning commercial FTP components ill-advisable for many users.
One of the more interesting aspects of FTP is that it uses two connections for communications rather than a single connection used by most other protocols such as HTTP or SMTP. The first connection is the Control connection, which is responsible for log-ins and command processing. This connection normally occurs over port 21 and uses the Telnet protocol for communications. The second connection is the Data connection which is responsible for sending files to the server, receiving files from the server, and sending directory listings from the server. Unlike the Control connection, the Data connection remains open only when data is transferred and only a single Data connection is available at one time; however, data can be uploaded and downloaded simultaneously over that connection. The operational process of communications over the Data connection consists of a client choosing an unused port to listen for the incoming data connection. Then, the client lets the server know which port is listening by sending a PORT command over the Control connection. This is followed by a follow-up command over the Control connection to initiate an action such as STOR or RETR. The server then connects to the client and begins the transfer of data.
.NET 2.0 FTP Implementation The next unusual aspect of the implementation is a result of using the WebRequest/WebResponse, which means that the programmatic model is URI based (rather than the more intuitive approach of specifying a server, location, and filename). In this model, every request requires a valid URI such as ftp://balrog/source when creating a request for a file list. This is fine when working with HTTP, as every request is stateless, but when attempting to carry out a series of actions in FTP, specifying a new request with a URI for each action quickly becomes unwieldy. Further complicating the architecture is the requirement to understand the underlying connection model to effectively implement a series of commands. By default, KeepAlive is true, which is as it should be, as KeepAlive specifies whether the control connection to the FTP server is closed after the request completes. The non-intuitive aspect is that to close the connection, KeepAlive must be set to false during the last request, which will issue a QUIT command to the server. A more intuitive approach would be to have a more direct mechanism to close the connection, such as a Close method. To specify which operation to execute, the WebRequestMethods.Ftp structure is used. While this structure supports most of the common operations such as WebRequestMethods.Ftp.ListDirectoryDetails and WebRequestMethods.Ftp.DownloadFile, a number of commands are missing. The most notable absent commands are directory navigation, which is understandable as a request/response model makes such commands more complicated to implement. This does not mean that there is no way to send custom commands. While FtpWebRequest.Method is normally used with the WebRequestMethods.Ftp structure, any valid command that a server will recognize can be specified as a string. This string can be a command or a series of commands that are separated by a "\n" character. Unfortunately, the Method property does not allow the use of a custom command that requires accompanying data or one that requires the server to respond to the command with data. Microsoft also warns that no command should be sent that will alter the state of the connection, such as MODE, PASV, or PORT. On a more positive note, Microsoft did include support for SSL-based security in the FTP implementation with the FtpWebRequest.EnableSsl and FtpWebRequest.ClientCertificates properties. The technique they use is Explicit security, which sends an AUTH TLS command. While Explicit security is the most common approach for encrypting FTP communications, a technique that is absent is Implicit security, which does not send any command, but rather expects to establish a secure connection immediately after establishing the TCP connection. Supporting both techniques guarantees the widest possible security compatibility, but supporting Explicit should be sufficient. Finally, the one missing element that is probably my greatest personal pet peeve is the lack of directory-list parsing. Identifying files from a directory command is a very common task, and while the parsing code can be written manually, supporting both the MS-DOS style listing and the various UNIX listings can be a time-consuming activity, especially in the area of maintenance. For simple FTP operations, such as uploading or downloading a file, the FtpWebRequest/FtpWebResponse classes can be bypassed by using System.Net.WebClient. This class will support http:, https:, ftp:, and file: scheme identifiers, and is useful in very simple scenarios.
The Sample Application In the sample application visible in Listing 1, Steps 1-5 demonstrate the code necessary to retrieve a directory list from an FTP server. The basic process is to initialize an FtpWebRequest class with the URI as demonstrated below: FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(ftpServer + remoteDir); This is the first step in every type of FTP request. The next step is to instantiate a NetworkCredential class. If this step is skipped, the request will be assumed as anonymous. Remember to repeat this for every request, even on the same connection, and to make sure not to change the information unless you plan to make a new connection.
NetworkCredential credentials = new NetworkCredential(username, password); The third step is to specify the command to execute: listRequest.Method = WebRequestMethods.Ftp.ListDirectory; The fourth step is to initialize the object to hold the response: FtpWebResponse listResponse = (FtpWebResponse)listRequest.GetResponse(); The last step is to read the data from the response: reader = new StreamReader(listResponse.GetResponseStream()); This order of operation is repeated for most activities that read data from the server, with the exception of uploading, where data is written to the RequestStream. Steps 6-12 demonstrate the file downloading process and Steps 13-22 explain file uploading, which as mentioned above, does differ slightly from the data retrieval model. While these three operations look like disparate processes in code, they are in fact occurring over a single connection in a non-broken stream of client-server communications. Listing 2 is a record of the FTP communications for the code discussed above and fully demonstrates how state is preserved until the connection is closed at the end of the upload process. (Listing 2)
Conclusion YOUR FEEDBACK
MICROSOFT .NET LATEST STORIES
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK BREAKING NEWS FROM THE WIRES
|
||||||||||||||||||||||||||||||||||||