FileSwapper contains the minimum amount of code needed to show a complete, well-designed framework for peer-to-peer request handling. It still lacks a number of niceties that you'd want to add in a production-level application. Some of these possible enhancements are listed here:
Currently, new files that are downloaded to the shared directory are ignored. That means that any files you download will not be shared with other users unless you restart the application. To solve this problem, you could add a timer that periodically refreshes the catalog with the server, or you could use a FileSystemWatcher to monitor the directory. You might even want to add discovery-service methods to publish individual files and reduce the bandwidth and database effort required when single files are added.
Currently, there's no ability for the user to cancel in-progress downloads. This would be easy to add, because each FileDownloadClient object stores the related ListViewItem. If a user selects a download to cancel from the ListView, you would simply have to look up the FileDownloadClient that references the corresponding ListViewItem and call its Abort() method.
You could enhance the communication used between peers. For example, the uploading peer could send a status message before every chunk of data. Similarly, after every chunk of data, the downloading peer could send a single byte indicating whether it was ready to receive more data, about to cancel the download, or in some other state.
You could improve the shutdown code by adding some sort of flag that can be set to instruct the download and upload threads to shut down, so that the application would not need to abort them forcefully. You might also want to poll for connection requests in the FileServer class using the TcpClient.Pending() method, and only call TcpClient.AcceptTcpClient() once a connection request has been received. This way, the thread will remain responsive and can be shut down more easily. Fortunately, .NET networking is very friendly—although these touches would improve the application, they aren't at all necessary.
Currently, the error handling is quite rudimentary. You could add more sophisticated exception handlers to log problems, inform the user, and protect the application.