Exemple #1
0
        private async void Run()
        {
            byte[] buffer;
            while (true)
            {
                buffer = await client.Receive(remotePoint);

                object msgObj  = FormatterHelper.Deserialize(buffer);
                Type   msgType = msgObj.GetType();
                if (msgType == typeof(ListUserResponseMessage))
                {
                    // 转换消息
                    ListUserResponseMessage usersMsg = (ListUserResponseMessage)msgObj;
                    // 更新用户列表
                    userList.Clear();
                    foreach (User user in usersMsg.UserList)
                    {
                        userList.Add(user);
                    }
                    this.DisplayUsers(userList);
                }
                else if (msgType == typeof(PingMessage))
                {
                    // 转换消息
                    PingMessage purchReqMsg = (PingMessage)msgObj;
                    // 发送打洞消息到远程主机
                    TrashMessage trashMsg = new TrashMessage();
                    buffer = FormatterHelper.Serialize(trashMsg);
                    client.Send(buffer, buffer.Length, purchReqMsg.RemotePoint);
                }
                else if (msgType == typeof(P2PTextMessage))
                {
                    // 转换消息
                    P2PTextMessage workMsg = (P2PTextMessage)msgObj;
                    Console.WriteLine("Receive a message: {0}", workMsg.Message);
                    // 发送应答消息
                    P2PAckMessage ackMsg = new P2PAckMessage();
                    buffer = FormatterHelper.Serialize(ackMsg);
                    client.Send(buffer, buffer.Length, remotePoint);
                }
                else if (msgType == typeof(P2PAckMessage))
                {
                    this.ReceivedACK = true;
                }
                else if (msgType == typeof(TrashMessage))
                {
                    Console.WriteLine("Recieve a trash message");
                }
                Thread.Sleep(100);
            }
        }
Exemple #2
0
        /// <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++)
            {
                P2PTextMessage workMsg = new P2PTextMessage(message);
                byte[]         buffer  = FormatterHelper.Serialize(workMsg);
                client.Send(buffer, buffer.Length, toUser.NetPoint);

                // 等待接收线程将标记修改
                for (int j = 0; j < 10; j++)
                {
                    if (this.ReceivedACK)
                    {
                        this.ReceivedACK = false;
                        return(true);
                    }
                    else
                    {
                        Thread.Sleep(300);
                    }
                }

                // 没有接收到目标主机的回应,认为目标主机的端口映射没有
                // 打开,那么发送请求信息给服务器,要服务器告诉目标主机
                // 打开映射端口(UDP打洞)
                TranslateMessage transMsg = new TranslateMessage(myName, toUserName);
                buffer = FormatterHelper.Serialize(transMsg);
                client.Send(buffer, buffer.Length, hostPoint);

                // 等待对方先发送信息
                Thread.Sleep(100);
            }
            return(false);
        }
Exemple #3
0
        /// <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++)
            {
                P2PTextMessage workMsg = new P2PTextMessage(message);
                byte[] buffer = FormatterHelper.Serialize(workMsg);
                client.Send(buffer, buffer.Length, toUser.NetPoint);

                // 等待接收线程将标记修改
                for (int j = 0; j < 10; j++)
                {
                    if (this.ReceivedACK)
                    {
                        this.ReceivedACK = false;
                        return true;
                    }
                    else
                    {
                        Thread.Sleep(300);
                    }
                }

                // 没有接收到目标主机的回应,认为目标主机的端口映射没有
                // 打开,那么发送请求信息给服务器,要服务器告诉目标主机
                // 打开映射端口(UDP打洞)
                TranslateMessage transMsg = new TranslateMessage(myName, toUserName);
                buffer = FormatterHelper.Serialize(transMsg);
                client.Send(buffer, buffer.Length, hostPoint);

                // 等待对方先发送信息
                Thread.Sleep(100);
            }
            return false;
        }