2. P2Pserver
namespace P2P.P2PServer
{

using System;

using System.Net;

using System.Net.Sockets;

using System.Threading;

using P2P.WellKnown;

/// <summary>

/// AppClass 的摘要说明。

/// </summary>

public class AppClass

{

public static void Main()

{

Server server = new Server();

try

{

server.Start();

Console.ReadLine();

server.Stop();

}

catch

{

}

}

}

/// <summary>

/// Server 的摘要说明。

/// </summary>

public class Server

{

private UdpClient server;

private UserCollection userList;

private Thread serverThread;

private IPEndPoint remotePoint;


public Server()

{

userList = new UserCollection();

remotePoint = new IPEndPoint(IPAddress.Any, 0);

serverThread = new Thread(new ThreadStart(Run));

}


public void Start()

{

try

{

server = new UdpClient(P2PConsts.SRV_PORT);

serverThread.Start();

Console.WriteLine("P2P Server started, waiting client connect...");

}

catch(Exception exp)

{

Console.WriteLine("Start P2P Server error: " + exp.Message);

throw exp;

}

}


public void Stop()

{

Console.WriteLine("P2P Server stopping...");

try

{

serverThread.Abort();

server.Close();

Console.WriteLine("Stop OK.");

}

catch(Exception exp)

{

Console.WriteLine("Stop error: " + exp.Message);

throw exp;

}


}


private void Run()

{

byte[] buffer = null;

while (true)

{

byte[] msgBuffer = server.Receive(ref remotePoint);

try

{

object msgObj = FormatterHelper.Deserialize(msgBuffer);

Type msgType = msgObj.GetType();

if (msgType == typeof(P2P.WellKnown.C2S.LoginMessage))

{

// 转换接受的消息

P2P.WellKnown.C2S.LoginMessage lginMsg = (P2P.WellKnown.C2S.LoginMessage)msgObj;

Console.WriteLine("has an user login: {0}", lginMsg.UserName);

// 添加用户到列表

IPEndPoint userEndPoint = new IPEndPoint(remotePoint.Address, remotePoint.Port);

User user = new User(lginMsg.UserName, userEndPoint);

userList.Add(user);

// 发送应答消息

P2P.WellKnown.S2C.GetUsersResponseMessage usersMsg = new P2P.WellKnown.S2C.GetUsersResponseMessage(userList);

buffer = FormatterHelper.Serialize(usersMsg);

server.Send(buffer, buffer.Length, remotePoint);

}

else if (msgType == typeof(P2P.WellKnown.C2S.LogoutMessage))

{

// 转换接受的消息

P2P.WellKnown.C2S.LogoutMessage lgoutMsg = (P2P.WellKnown.C2S.LogoutMessage)msgObj;

Console.WriteLine("has an user logout: {0}", lgoutMsg.UserName);

// 从列表中删除用户

User lgoutUser = userList.Find(lgoutMsg.UserName);

if (lgoutUser != null)

{

userList.Remove(lgoutUser);

}

}

else if (msgType == typeof(P2P.WellKnown.C2S.TranslateMessage))

{

// 转换接受的消息

P2P.WellKnown.C2S.TranslateMessage transMsg = (P2P.WellKnown.C2S.TranslateMessage)msgObj;

Console.WriteLine("{0}(1) wants to p2p {2}", remotePoint.Address.ToString(), transMsg.UserName, transMsg.ToUserName);

// 获取目标用户

User toUser = userList.Find(transMsg.ToUserName);

// 转发Purch Hole请求消息

if (toUser == null)

{

Console.WriteLine("Remote host {0} cannot be found at index server", transMsg.ToUserName);


}

else

{

P2P.WellKnown.S2C.SomeOneCallYouMessage transMsg2 = new P2P.WellKnown.S2C.SomeOneCallYouMessage(remotePoint);

buffer = FormatterHelper.Serialize(transMsg);

server.Send(buffer, buffer.Length, toUser.NetPoint);



}

}

else if (msgType == typeof(P2P.WellKnown.C2S.GetUsersMessage))

{

// 发送当前用户信息到所有登录客户

P2P.WellKnown.S2C.GetUsersResponseMessage srvResMsg = new P2P.WellKnown.S2C.GetUsersResponseMessage(userList);


buffer = FormatterHelper.Serialize(srvResMsg);

foreach(User user in userList)

{

server.Send(buffer, buffer.Length, user.NetPoint);

}

}

Thread.Sleep(500);

}

catch{}

}

}

}
}


3. P2Pclient
namespace P2P.P2PClient
{

using System;

using System.Net;

using System.Net.Sockets;

using System.Threading;

using P2P.WellKnown;

///
<summary>


/// AppClass 的摘要说明。

///
</summary>


public class AppClass

{

public static void Main()

{

Client client = new Client("202.96.134.103");

client.ConnectToServer("myname", "mypassword");

client.Start();

Console.WriteLine("test arguments");

while (true)

{

string str = Console.ReadLine();

client.PaserCommand(str);

}

}

}

/// <summary>

/// Client 的摘要说明。

/// </summary>

public class Client : IDisposable

{

private const int MAXRETRY = 10;

private UdpClient client;

private IPEndPoint hostPoint;

private IPEndPoint remotePoint;

private UserCollection userList;

private string myName;

private bool ReceivedACK;

private Thread listenThread;


public Client(string serverIP)

{

ReceivedACK = false;

remotePoint = new IPEndPoint(IPAddress.Any, 0);

hostPoint = new IPEndPoint(IPAddress.Parse(serverIP), P2PConsts.SRV_PORT);

client = new UdpClient();

userList = new UserCollection();

listenThread = new Thread(new ThreadStart(Run));

}


public void Start()

{

if (this.listenThread.ThreadState==ThreadState.Unstarted)

{

this.listenThread.Start();

Console.WriteLine("You can input you command:"n");

Console.WriteLine("Command Type:""send"",""exit"",""getu""");

Console.WriteLine("Example : send Username Message");

Console.WriteLine("
exit");


Console.WriteLine("
getu");


}

}


public void ConnectToServer(string userName, string password)

{

myName = userName;

// 发送登录消息到服务器

P2P.WellKnown.C2S.LoginMessage lginMsg = new P2P.WellKnown.C2S.LoginMessage(userName, password);

byte[] buffer = FormatterHelper.Serialize(lginMsg);

client.Send(buffer, buffer.Length, hostPoint);

// 接受服务器的登录应答消息

buffer = client.Receive(ref remotePoint);

P2P.WellKnown.S2C.GetUsersResponseMessage srvResMsg = (P2P.WellKnown.S2C.GetUsersResponseMessage)FormatterHelper.Deserialize(buffer);

// 更新用户列表

userList.Clear();

foreach(User user in srvResMsg.UserList)

{

userList.Add(user);

}

this.DisplayUsers(userList);

}


/// <summary>

/// 这是主要的函数:发送一个消息给某个用户(C)

/// 流程:直接向某个用户的外网IP发送消息,如果此前没有联系过

/// 那么此消息将无法发送,发送端等待超时。

/// 超时后,发送端将发送一个请求信息到服务端,要求服务端发送

/// 给客户C一个请求,请求C给本机发送打洞消息

/// *以上流程将重复MAXRETRY次

/// </summary>

/// <param name="toUserName">对方用户名</param>

/// <param name="message">待发送的消息</param>

/// <returns></returns>

private bool SendMessageTo(string toUserName, string message)

{

User toUser = userList.Find(toUserName);

if (toUser == null)

{

return false;

}

for (int i=0; i<MAXRETRY; i++)

{

P2P.WellKnown.P2P.WorkMessage workMsg = new P2P.WellKnown.P2P.WorkMessage(message);

byte[] buffer = FormatterHelper.Serialize(workMsg);

相关文章:

  • 2021-12-29
  • 2021-08-05
猜你喜欢
  • 2022-12-23
  • 2021-11-22
  • 2022-02-12
相关资源
相似解决方案