典型 P2P 包含中央索引服務器(不存文件,只存用戶信息、IP、共享文件列表)與多個客戶端。流程:
.NET 內置 TcpListener (服務端) 和 TcpClient (客戶端) 讓 P2P 開發極簡。
public class Transfer
{
private TcpListener _listener;
private int _port = 8081;
public Transfer()
{
_listener = new TcpListener(IPAddress.Any, _port);
}
public void ListenForPeers()
{
_listener.Start();
while (true)
{
using (Socket socket = _listener.AcceptSocket())
using (NetworkStream stream = new NetworkStream(socket))
{
// 讀取請求文件名 (256 bytes)
byte[] buffer = new byte[256];
stream.Read(buffer, 0, buffer.Length);
string filename = Encoding.ASCII.GetString(buffer).TrimEnd('\0');
filename = filename.Replace("/", "\\"); // 路徑標準化
// 發送文件
using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
using (BinaryReader br = new BinaryReader(fs))
{
byte[] fileBuffer = new byte[1024];
int read;
while ((read = br.Read(fileBuffer, 0, fileBuffer.Length)) > 0)
stream.Write(fileBuffer, 0, read);
}
}
}
}
}
public void DownloadToClient(string serverIp, string remoteFilename, string localFilename)
{
using (TcpClient client = new TcpClient())
{
client.Connect(serverIp, _port);
using (NetworkStream stream = client.GetStream())
{
// 發送文件名
byte[] nameBytes = Encoding.ASCII.GetBytes(remoteFilename);
stream.Write(nameBytes, 0, nameBytes.Length);
// 接收文件
using (FileStream fs = new FileStream(localFilename, FileMode.Create))
using (BinaryWriter bw = new BinaryWriter(fs))
{
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
bw.Write(buffer, 0, bytesRead);
}
}
}
}
| 技術 | 說明 |
|---|---|
| TcpListener | 服務端綁定端口,AcceptSocket 阻塞等待連接 |
| NetworkStream | 基於 Socket 的流式讀寫,簡化字節傳輸 |
| BinaryReader/Writer | 高效二進制塊讀寫 |
| using 語句 | 確保 Socket、Stream、File 等非托管資源及時釋放 |
BeginAcceptSocket/Task.Run) 支持並發..\\)