c.建立p2p會話
private void ProcP2PPurchHoleMsg(Packet packet,IPEndPoint remoteEP)
{
//打洞請求消息
P2PPurchHolePacket purchReqMsg = (P2PPurchHolePacket)packet;
PeerEntity toUser = userList.Single(c => c.UserName == purchReqMsg.ToUserName);
PeerEntity user = userList.Single(c => c.UserName == purchReqMsg.UserName);
toUser.P2PAddress = toUser.RemoteEndPoint;
printf("Set P2P Address for {0}->[{1}]", user.UserName, toUser.P2PAddress.ToString());
//uPnp實現端口映射
if(NAT.AddPortMapping(toUser.P2PAddress.Port, ProtocolType.Udp, "AddPortMapping"))
printf("Port mapping successed!");
// 發送打洞消息到遠程主機
P2PPurchHoleAckPacket trashMsg = new P2PPurchHoleAckPacket (purchReqMsg.UserName, purchReqMsg.ToUserName);
byte[] buffer = UtilityHelper.Serialize(trashMsg);
clIEnt.Send(buffer, buffer.Length, user.RemoteEndPoint);
}
3、服務端
a、消息處理線程
private void RecvThreadProc()
{
IPEndPoint remotePoint = null;
byte[] msgBuffer = null;
while (true)
{
msgBuffer = server.Receive(ref remotePoint);
try
{
object msgObj = UtilityHelper.Deserialize (msgBuffer);
switch ((msgObj as Packet).GetCommandType())
{
case Command.MSG_USERLOGIN: //用戶登錄
ProcUserLoginMsg(msgObj as UserLoginPacket, remotePoint);
break;
case Command.MSG_USERLOGOUT: //退出登錄
ProcUserLogoutMsg(msgObj as UserLogoutPacket, remotePoint);
break;
case Command.MSG_GETUSERLIST: //所有用戶列表
ProcGetUserListMsg(msgObj as UserListPacket, remotePoint);
break;
case Command.MSG_P2PCONNECT: //點對點連接信息
ProcP2PConnectMsg(msgObj as P2PConnectionPacket, remotePoint);
break;
case Command.MSG_USERACTIVEQUERY: // 用 戶對服務器輪詢的應答
ProcUserActiveQueryMsg(msgObj as UserActiveQueryPacket, remotePoint);
break;
}
Thread.Sleep(100);
}
catch { }
}
}