示例#1
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);
        }
示例#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;
        }
示例#3
0
        private async void Run()
        {
            byte[] buffer = null;
            while (true)
            {
                byte[] msgBuffer = await server.Receive(remotePoint);

                try
                {
                    object msgObj  = FormatterHelper.Deserialize(msgBuffer);
                    Type   msgType = msgObj.GetType();
                    if (msgType == typeof(LoginMessage))
                    {
                        // 转换接受的消息
                        LoginMessage lginMsg = (LoginMessage)msgObj;
                        Console.WriteLine("{0}: user {1} sign in.", System.DateTime.Now.ToString(), lginMsg.UserName);

                        // 添加用户到列表
                        IPEndPoint userEndPoint = new IPEndPoint(remotePoint.Address, remotePoint.Port);
                        User       user         = new User(lginMsg.UserName, userEndPoint);
                        userList.Add(user);

                        // 发送应答消息
                        ListUserResponseMessage usersMsg = new ListUserResponseMessage(userList);
                        buffer = FormatterHelper.Serialize(usersMsg);
                        server.Send(buffer, buffer.Length, remotePoint);
                        Console.WriteLine("Send:" + usersMsg);
                    }
                    else if (msgType == typeof(LogoutMessage))
                    {
                        // 转换接受的消息
                        LogoutMessage lgoutMsg = (LogoutMessage)msgObj;
                        Console.WriteLine("{0}: {1} sign out", System.DateTime.Now.ToString(), lgoutMsg.UserName);

                        // 从列表中删除用户
                        User lgoutUser = userList.Find(lgoutMsg.UserName);
                        if (lgoutUser != null)
                        {
                            userList.Remove(lgoutUser);
                        }
                    }
                    else if (msgType == typeof(TranslateMessage))
                    {
                        // 转换接受的消息
                        TranslateMessage transMsg = (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
                        {
                            PingMessage transMsg2 = new PingMessage(remotePoint);
                            buffer = FormatterHelper.Serialize(transMsg);
                            server.Send(buffer, buffer.Length, toUser.NetPoint);
                            Console.WriteLine("Send:" + transMsg2);
                        }
                    }
                    else if (msgType == typeof(ListUserMessage))
                    {
                        // 发送当前用户信息到所有登录客户
                        ListUserResponseMessage srvResMsg = new ListUserResponseMessage(userList);
                        buffer = FormatterHelper.Serialize(srvResMsg);
                        foreach (User user in userList.InnerList)
                        {
                            server.Send(buffer, buffer.Length, user.NetPoint);
                            Console.WriteLine("Send:" + srvResMsg);
                        }
                    }
                    Thread.Sleep(500);
                }
                catch (Exception e)
                {
                    System.Console.WriteLine(e.Message);
                    System.Console.WriteLine(e.StackTrace);
                }
            }
        }