P2P And C#
By Shripad Kulkarni
http://www.csharphelp.com/archives/archive261.html
This article describes the simple approach to design a peer to peer network.
The figure1 shown below gives a general idea how p2p works. Although there are many other types where index server or central servers are not required , or can be eliminated so client talk directly to other clients.
The P2P concept generally consists of a central Index server. This server does not contain any files, physically. It only maintains the information about the users who are logged on to the network, the IP address of the client and the list of files shared at any given moment by a user. The client and the server communicate with each other over a socket connection using simple commands.
When a client "A" wants to search for files shared by other clients on the P2P network
?The Client "A"logs into the index server with a userid and the folder information that the client is willing to share.
?The Client "A" registers all the files with the server so that other clients can search for these files.
?The Client "A" makes a request to the index server to search files matching a given input pattern.
?The index server searches files names in its repository and returns to the Client "A"
The user sharing the file eg Client "B"
IP address of the user
Files names that it found.
Once the Client "A" selects the download option, Client "A" makes a socket connection to the Client "B" using the IP address returned by search.
You can define any port that you wish to listen at. For a list of TCP ports and what port numbers that can be used click here
If there is a successful connection is establised, inform the other client to begin sending the file.
Once the download is complete, register this file with the index server as your copy of the shared file.
Such a P2P network can be used to share any type of file. It can be used for your local network or a global network.
For more information about Firewall and SOCKS click here
The C# language make life very easy with the help of the TCPListener and the TCPClient classes.
Here is a listing of the transfer class ..
public MyTcpListener(int port) : base(port)
{
}
public void StopMe()
{
if ( this.Server != null )
{
this.Server.Close();
}
}
}
///
/// Summary description for Transfer.
///
public class Transfer
{
MyTcpListener tcpl;
public Transfer()
{
OptionsLoader ol = new OptionsLoader();
int port = 8081;
if (ol.Port > 0)
{
port = ol.Port;
}
else
{
// The default in case nothing else is set
port = 8081;
}
this.tcpl = new MyTcpListener(port);
}
public void TransferShutdown()
{
tcpl.StopMe();
}
public void ListenForPeers()
{
try
{
Encoding ASCII = Encoding.ASCII;
tcpl.Start();
while (true)
{
// Accept will block until someone connects
Socket s = tcpl.AcceptSocket();
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)
{
DataStream.Write(bytes, 0, read);
}
reader.Close();
DataStream.Flush();
DataStream.Close();
}
}
catch(SocketException ex)
{
MessageBox.Show(ex.ToString());
}
}
public void DownloadToClient(String server, string remotefilename, string localfilename)
{
try
{
TcpClient tcpc = new TcpClient();
Byte[] read = new Byte[1024];
OptionsLoader ol = new OptionsLoader();
int port = 0;
if (ol.Port > 0)
{
port = ol.Port;
}
else
{
// The default in case nothing else is set
port = 8081;
}
// Try to connect to the server
IPHostEntry IPHost = Dns.Resolve(server);
string []aliases = IPHost.Aliases;
IPAddress[] addr = IPHost.AddressList;
IPEndPoint ep = new IPEndPoint(addr[0], port);
tcpc.Connect(ep);
// 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 and convert it to ASII
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)
{
throw new Exception(ex.ToString());
}
}
}
}
[此贴子已经被作者于2006-11-15 16:22:46编辑过]