いくつかの背景、トラッカーに登録されたピア間の P2P 接続を作成できる単純なアプリを作成しようとしている、ちょっとゼロから P2P アーキテクトを作成しようとしている XD (ヘルプまたはリソースをくださいO _ O )
trackerServerは、接続されたクライアントソケット情報をリストに保持し、リクエストのためにクエリを実行するだけです
namespace PeerTrackerServer
{
public class PeerSockets
{
public string PeerName { get; set; }
public byte[] SocketInformation { get; set; }
}
public class NetworkCommandMessage
{
public NetworkCommandMessage(byte[] command)
{
var strData = UTF8Encoding.UTF8.GetString(command);
var arrSplited = strData.Split(':');
this.Command = arrSplited[0].ToLower().Trim();
this.Data = arrSplited[1].Replace("\0","").ToLower().Trim();
}
public string Command { get; set; }
public string Data { get; set; }
}
class Program
{
public static List<PeerSockets> _Peers;
static void Main(string[] args)
{
_Peers = new List<PeerSockets>();
var srvSocket = new TcpListener(IPAddress.Any, 1313);
srvSocket.Start();
while (true)
{
var client = srvSocket.AcceptSocket();
var tsk = new Task(new Action(() => { PeerHandler(client); }));
tsk.Start();
}
}
public static void PeerHandler(Socket client)
{
var commandBuff = new byte[128];
client.Receive(commandBuff);
var netMSG = new NetworkCommandMessage(commandBuff);
switch (netMSG.Command)
{
case "register":
var duplicatedSocket = client.DuplicateAndClose(Process.GetCurrentProcess().Id);
_Peers.Add(new PeerSockets
{
PeerName = netMSG.Data,
SocketInformation = duplicatedSocket.ProtocolInformation
});
break;
case "connect":
var requestedUser = _Peers.Where(c => c.PeerName == netMSG.Data).FirstOrDefault();
if (requestedUser != null)
{
client.Send(requestedUser.SocketInformation);
client.Close();
}
else
{
var msg = UTF8Encoding.UTF8.GetBytes("Requested User Not Found !");
client.Send(msg);
client.Close();
}
break;
}
}
}
}
Client_1は自分自身を Tracker Server と Server に登録します そのソケットを複製し、それを維持します (いつまで続くかはわかりません! ^_^ )
namespace Client_1
{
class Program
{
public static Socket _Socket;
static void Main(string[] args)
{
//Register To Tracker Server
var tsk = new Task(new Action(() => { RegisterMe(); }));
tsk.Start();
tsk.Wait();
//Start Receiving Data
var buff = new byte[4096];
var ns = new NetworkStream(_Socket, true);
var readCount = 0;
while ((readCount = ns.Read(buff,0,buff.Length))>0)
{
var strData = UTF8Encoding.UTF8.GetString(buff, 0, readCount);
Console.Write(strData);
}
}
public static void RegisterMe()
{
var registerBuffer = new byte[128];
var tcpClient = new TcpClient("127.0.0.1", 1313);
var registerCommand = "register:Client1";
var cmdData = UTF8Encoding.UTF8.GetBytes(registerCommand);
Array.Copy(cmdData, registerBuffer, cmdData.Length);
var ns = tcpClient.GetStream();
ns.Write(registerBuffer, 0, registerBuffer.Length);
ns.Flush();
_Socket = tcpClient.Client;
}
}
}
ここでは、Client_2が複製された Client_1 ソケット情報を受信し、ソケットを再作成しようとしています。client_1 は現在受信データを待機しています。
namespace Client_2
{
class Program
{
static void Main(string[] args)
{
var buffConnect = new byte[128];
var cmdConnect = "connect:Client1";
var cmdData = UTF8Encoding.UTF8.GetBytes(cmdConnect);
Array.Copy(cmdData, buffConnect, cmdData.Length);
//send Connect Command
var tcpClient = new TcpClient("127.0.0.1", 1313);
var ns = tcpClient.GetStream();
ns.Write(buffConnect, 0, buffConnect.Length);
ns.Flush();
//Wait For ProtocolSocketInformation
var buff = new byte[32*4096];
var readBytes = 0;
readBytes = ns.Read(buff, 0, buff.Length);
var sockProtocolInfo = new byte[readBytes];
Array.Copy(buff,sockProtocolInfo,readBytes);
//Create New Socket
var peerSocketInfo = new SocketInformation();
peerSocketInfo.ProtocolInformation = sockProtocolInfo;
peerSocketInfo.Options = SocketInformationOptions.Connected;
/*
* HERE IS THE ERROR ArgumentException : "The specified value for the socket information is invalid"
*/
var peerSocket = new Socket(peerSocketInfo);
//Send Message To Peer Client
var msg = UTF8Encoding.UTF8.GetBytes("\r\n\r\nYoo there ! Im From Client 2!\r\n");
var peerNS = new NetworkStream(peerSocket);
peerNS.Write(msg, 0, msg.Length);
peerNS.Flush();
peerNS.Close();
}
}
}