Figure 1
Figure 1 .NET Framework Features
Feature |
Description |
Data |
Classes that expose XML and ADO-style data manipulation |
Windows Forms |
Classes that make it easier to write Windows-based GUI applications and rich controls |
ASP.NET |
Support for building server-based Web applications—both Web UI (either HTML or WML) as well as XML Web Services |
Base types |
Base classes used by the rest of the framework for common tasks such as strings, collections, and array manipulation |
Services |
Support for working with Windows Service Applications, Microsoft Message Queue, and other system-level features |
Network |
Classes that provide support for creating applications that use Internet protocols to send and receive data |
Figure 5 C# Server Code for a Web Service
<%@ WebService Language="C#" Class="P2PService" %>
public class P2PService : WebService
{
public static ArrayList PeerFiles;
private static String MyLock = "lock";
// For the sake of simplicity, this sample is using an ArrayList
// to store peer information in memory.
// This information could be stored in a file, database, or by some
// other means.
P2PService()
{
if( null == PeerFiles)
{
lock(MyLock)
{
if( null == PeerFiles )
PeerFiles = new ArrayList();
}
}
}
[WebMethod]
public int GetNumUsers()
{
// Get the count of all registered users
return users.Count;
}
[WebMethod]
public int ClearEntriesForPeer(string hostname)
{
// Unregister code goes here
return NumEntriesCleared;
}
[WebMethod]
public int GetNumFiles()
{
return PeerFiles.Count;
}
[WebMethod]
public int RegisterFile(string hostname, string name,
string connection, string size)
{
// Registration code here
return PeerFiles.Count;
}
[WebMethod]
public PeerFile[] GetPeerFilesInfo()
{
return (PeerFile[])PeerFiles.ToArray(typeof(PeerFile));
}
[WebMethod]
public PeerFile[] FindPeersWithFiles(string Search)
{
// Lookup code goes here
return (PeerFile[])MatchingPeers.ToArray(typeof(PeerFile));
}
}
public class PeerFile : IComparable
{
public string IpAddress;
public string Name;
public string Connection;
public string Size;
}
Figure 6 P2PService Class
Method |
Description |
GetNumUsers |
Useful for querying the service to find out how many peers are currently registered with the service. |
ClearEntriesForPeer |
Provides a basic unregistration capability. This method is called by the client upon shutdown. Note that in a more robust service, the registration entries would be more likely to follow some type of a lease model where entries are timed out at regular intervals if no activity, or heartbeat, from the peer that registered the files has occurred over a significant period of time |
GetNumFiles |
Used for telling the peer how many files are currently registered with the service. |
RegisterFile |
Called by the peer to register a file with the peer service. |
GetPeerFilesInfo |
Used mostly for diagnostic purposes. It returns an array of all peer files currently registered with the service. |
FindPeersWithFiles |
Key method for searching the list of registered files for a match. It returns an array of peer file information classes that give the peer the information it needs to contact another peer and request a file transfer. |
Figure 7 C# Client Code for the Web Service
// Using the Web Service client proxy code to hit the service
//Get other servers
P2Pservice s = new P2PService();
// Register a file with the service
s.RegisterFile("dnsname", "Service Information.doc", "Cable", "29423");
// Get the number of other peers registered
int NumPeers = s.GetNumPeers();
// Query the service for some content
PeerFile[] Files = s.FindPeersWithFiles("foo");
// Unregister files from the service
int NumFilesUnregistered = s.ClearEntriesForPeer("dnsname");
Figure 8 Peer Sending the File
public void ListenForPeers()
{
try
{
Encoding ASCII = Encoding.ASCII;
tcpl.Start();
while (true)
{
// Accept will block until someone connects
Socket s = tcpl.Accept();
NetworkStream DataStream = new NetworkStream(s);
String filename;
Byte[] Buffer = new Byte[256];
DataStream.Read(Buffer, 0, 256);
filename = Encoding.ASCII.GetString(Buffer);
StringBuilder sbFileName = new StringBuilder(filename);
StringBuilder sbFileName2 = sbFileName.Replace("\\", "\\\\");
FileStream fs = new FileStream(sbFileName2.ToString(),
FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(fs);
byte[] bytes = new byte[1024];
int read;
while((read = reader.Read(bytes, 0, bytes.Length)) != 0)
{
// Read from the file and write the data to the network
DataStream.Write(bytes, 0, read);
}
reader.Close();
DataStream.Flush();
DataStream.Close();
}
}
catch(SocketException ex)
{
MessageBox.Show(ex.ToString());
}
}
Figure 9 Peer Receiving the File
public void DownloadToClient(String server, string remotefilename,
string localfilename)
{
try
{
TCPClient tcpc = new TCPClient();
Byte[] read = new Byte[1024];
// Try to connect to the server
if (tcpc.Connect(server, 8081) == -1)
{
return;
}
// Get the stream
Stream s = tcpc.GetStream();
Byte[] b = Encoding.ASCII.GetBytes(remotefilename.ToCharArray());
s.Write( b, 0, b.Length );
int bytes;
FileStream fs = new FileStream(localfilename,
FileMode.OpenOrCreate);
BinaryWriter w = new BinaryWriter(fs);
// Read the stream
while( (bytes = s.Read(read, 0, read.Length)) != 0)
{
w.Write(read, 0, bytes);
read = new Byte[1024];
}
tcpc.Close();
w.Close();
fs.Close();
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Figure 10 Downloading HTML Content
// Create a WebRequest object passing in the desired URI to the .Create()
// method and then
// get a response from the server by calling .GetResponse();
WebRequest WReq = WebRequestFactory.Create("https://www.mypeer-to-
peer.com/news.htm");
WebResponse WResp = WReq.GetResponse();
// Get a readable stream from the server - Encode the data to ASCII for
// writing to the console
StreamReader sr = new StreamReader(WResp.GetResponseStream(),
Encoding.ASCII);
// Declare vars used for reading text
int length = 1024;
char [] Buffer = new char[1024];
int bytesread = 0;
//Read from the stream and write any data to the console
bytesread = sr.Read( Buffer, 0, length);
while( bytesread > 0 )
{
// If your application is a Windows Forms application, you might
// append this data using a StringBuilder and then hand the data
// to an HTML rendering control once it has all been downloaded.
Console.Write( Buffer,0, bytesread);
bytesread = sr.Read( Buffer, 0, length);
}
//Close the stream when finished
sr.Close();
Wresp.GetResponseStream().Close();