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();