// 以下内容用于建立P2P连接 /// <summary> /// 发起方请求Socket连接 /// </summary> /// <param name="UserToken">要发送的RTF文本/要发送的文件</param> /// <param name="isRtf">决定要发送的是什么</param> private void createSocket(string UserToken, bool isRtf) { try { // 新建一个封装的P2P通信类 Socket newSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); client = new P2PChatClient(owner, this, newSocket); if (isRtf) { client.rtfToSend = UserToken; } else { client.fileToSend = UserToken; } // 准备连接 SocketAsyncEventArgs saEA = new SocketAsyncEventArgs(); saEA.Completed += new EventHandler <SocketAsyncEventArgs>( client.createSocketCompletedEventHandler); saEA.RemoteEndPoint = new IPEndPoint( owner.remoteIPaddress[targetName].IpAddress, owner.PortTCPSend); // 连接 client.socket.ConnectAsync(saEA); } catch (Exception ex) { Trace.WriteLine("异常位置:createSocket"); Trace.WriteLine(ex.Message); } }
/// <summary> /// 将P2PChatClient与FormChat互相绑定 /// 如果没有FormChat则创建 /// </summary> /// <param name="p2pClient"></param> /// <param name="targetName">发起方的用户名</param> public void SetChatFormClient(P2PChatClient p2pClient, string targetName) { if (!formChats.ContainsKey(targetName)) { formChats.Add(targetName, new FormChat(this, targetName)); } formChats[targetName].SetHandlerForSocket(p2pClient); }
/// <summary> /// 设置与对方的P2PChatClient,并将P2PChatClient的owner设为自己。 /// 由于对方连接到自己而调用。 /// </summary> /// <param name="newSocketHandler"></param> public void SetHandlerForSocket(P2PChatClient newSocketHandler) { client = newSocketHandler; client.SetOwner(this); }
/// <summary> /// 接受方 /// 收到1次确认,判断连接的类型 /// </summary> /// <param name="sender"></param> /// <param name="ea"></param> private void firstAckReceivedEventHandler( object sender, EventArgs ea) { Socket rcvSocket = sender as Socket; try { // 接收到的异步Socket事件参数 SocketAsyncEventArgs socketAsyncEA = (SocketAsyncEventArgs)ea; // 提取接收到的文本 string rcvString = Encoding.ASCII.GetString(socketAsyncEA.Buffer); ProtocalHandler protocalHandler = new ProtocalHandler(MyName); // 是否是协议 if (!protocalHandler.SetXmlText(rcvString)) { throw new MyProtocalException( "不是有效的协议文本,找不到CSP2P标签"); } // 数据包类型 string type = protocalHandler.GetElementTextByTag("type"); if (type == null) { throw new MyProtocalException( "不是有效的1次确认,找不到type标签"); } if (type.Equals("closesocket")) // 对方要求关闭Socket { rcvSocket.Close(); } // 对方用户名 string targetNameBase64 = protocalHandler.GetElementTextByTag("name"); string targetName = protocalHandler.Base64stringToString(targetNameBase64); if (targetName == null) { throw new MyProtocalException( "不是有效的1次确认," + "找不到name标签"); } if (type.Equals("init_chat_request")) // 私聊 { P2PChatClient socketHandler = new P2PChatClient(this, rcvSocket); socketHandler.newSocketChatNameReceived(protocalHandler); } else if (type.Equals("init_gp_request")) // 群聊 { P2PGroupClient socketHandler = new P2PGroupClient(this, rcvSocket); socketHandler.newSocketGroupNamesReceived(protocalHandler); } else { throw new MyProtocalException( "不是有效的1次确认," + "type不为init_chat_request或init_gp_request"); } // 记录对方地址 if (remoteIPaddress.ContainsKey(targetName)) { remoteIPaddress[targetName] = new IPInfo((IPEndPoint)rcvSocket.RemoteEndPoint); } else { remoteIPaddress.Add(targetName, new IPInfo((IPEndPoint)rcvSocket.RemoteEndPoint)); } } catch (Exception ex) { Trace.WriteLine("异常位置:" + "firstAckReceivedEventHandler"); Trace.WriteLine(ex.Message); // 直接关闭socket try { rcvSocket.Close(); } catch (Exception ex2) { Trace.WriteLine("异常位置:" + "firstAckReceivedEventHandler出错关闭rcvSocket时"); Trace.WriteLine(ex2.Message); } } }