ChartServer

来源:互联网 发布:手机代理上网软件 编辑:程序博客网 时间:2024/05/29 10:48
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows;
using ChartClient.Model;


namespace ChartServer
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow
    {
        /// <summary>
        /// 处于连接状态的所有客户端列表
        /// </summary>
        private readonly List<Users> _userList = new List<Users>();


        private TcpListener _listener;
        private IPAddress _ip;


        bool isNormailExit = false;
        public bool isNormalExit { get; set; }




        //创建Socket
        //Socket client;


        public MainWindow()
        {
            InitializeComponent();
            Loaded += MainWindow_Loaded;
            Closed += MainWindow_Closed;
        }






        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());
            _ip = ips[ips.Length - 1];
            IpAddress.Text = _ip.ToString();


        }


        private void MainWindow_Closed(object sender, EventArgs e)
        {
            //退出监听
            if (_listener != null)
            {
                //停止服务
                _listener.Stop();
            }
        }


        /// <summary>
        /// 启动服务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Start_OnClick(object sender, RoutedEventArgs e)
        {


            //获取IP地址
            IPAddress ipAddress = _ip;
            //获取端口号
            int port = Convert.ToInt32(TbPort.Text);
                


            //绑定socket和端口号
            try
            {
                _listener = new TcpListener(ipAddress, port);


                //监听该端口号
                _listener.Start();


                //发布监听消息
                Logs.AppendText(string.Format("服务器:{0}  监听端口:{1}  开始监听 . . .", ipAddress, port) + "\n");




                //接收来自客户端的连接请求(线程)
                Thread clientConnectThread = new Thread(ListenClientConnect);
                //启动监听
                clientConnectThread.Start();


                Start.IsEnabled = false;
            }
            catch (Exception ex)
            {
                Logs.AppendText(ex.Message + "\n");


            }
            
        }


        /// <summary>
        /// 监听来自客户端的连接请求
        /// </summary>
        /// <param name="obj"></param>
        private void ListenClientConnect(object obj)
        {
            TcpClient thisClient = null;
            while (true)
            {
                try
                {
                    thisClient = _listener.AcceptTcpClient();
                }
                catch (Exception)
                {


                    break;
                }
                //每接收一个客户端连接,就创建一个对应的线程循环接收该客户端发来的信息;
                Users user = new Users(thisClient);
                //从socket 中读取字符
                Thread receiveMsgThread = new Thread(ReceiveMsg);
                //开启线程
                receiveMsgThread.Start(user);


                //xxx用户登录成功,当前连接用户数
                Logs.AppendText(string.Format("{0}登录系统  ", thisClient.Client.RemoteEndPoint ));
                Logs.AppendText(string.Format(" 当前在线用户:{0}", _userList.Count) + "\n");


            }
        }


        /// <summary>
        /// 从socket中接收来自客户端的数据
        /// </summary>
        /// <param name="clientmsg">客户端信息</param>
        private void ReceiveMsg(object clientmsg)
        {
            Users user = (Users)clientmsg;
            //获取客户端TcpClient
            TcpClient client = user.Client;


            while (isNormailExit == false)
            {
                //从网络中读取字符串
                string binaryDatamsg = null;
                try
                {
                    //二进制流转字符串
                    binaryDatamsg = user.BinaryDataReader.ReadString();
                }
                catch (Exception)
                {


                    if (isNormalExit == false)
                    {
                        Logs.AppendText(string.Format("与[{0}]失去联系,已终止接收该用户信息", client.Client.RemoteEndPoint) + "\n");
                        //将用户移除
                        RemoveUser(user);
                        
                    }
                    break;
                }
                //记录用户基本操作 如登录、注销、开始会话等
                
                Logs.AppendText(string.Format("来自{0}", user.Client.Client.RemoteEndPoint));
                Logs.AppendText(string.Format(" :{0}",binaryDatamsg)+"\n");
                string[] splitString = binaryDatamsg.Split(',');
                switch (splitString[0])
                {
                    case "Login": //登录
                        user.Name = splitString[1];
                        SendToAllClient(user, binaryDatamsg);
                        break;
                    case "Logout"://注销
                        SendToAllClient(user, binaryDatamsg);
                        RemoveUser(user);
                        return;
                    case "Talk":
                        string talkString = binaryDatamsg.Substring(splitString[0].Length + splitString[1].Length + 2);
                        Logs.AppendText(string.Format("{0}对{1}说:{2}", user.Name, splitString[1], talkString));


                        SendToClient(user, "talk," + user.Name + "," + talkString);
                        foreach (Users target in _userList)
                        {
                            if (target.Name == splitString[1] && user.Name != splitString[1])
                            {
                                SendToClient(target, "talk," + user.Name + "," + talkString);
                                break;
                            }
                        }
                        break;
                    default:
                        Logs.AppendText("什么意思啊:" + binaryDatamsg);
                        break;
                }


            }
        }


        /// <summary>
        /// 发送消息给指定用户
        /// </summary>
        /// <param name="user"></param>
        /// <param name="msg"></param>
        private void SendToClient(Users user, string msg)
        {
            try
            {
                //将字符串写入网络流,此方法会自动附加字符串长度前缀
                user.BinaryDataWriter.Write(msg);
                user.BinaryDataWriter.Flush();
                Logs.AppendText(string.Format("向[{0}]发送:{1}", user.Name, msg));
            }
            catch
            {
                Logs.AppendText(string.Format("向[{0}]发送信息失败", user.Name));
            }
        }


        /// <summary>
        /// 发送消息给所有客户端
        /// </summary>
        /// <param name="user"></param>
        /// <param name="binaryData"></param>
        private void SendToAllClient(Users user, string message)
        {
            string command = message.Split(',')[0].ToLower();
            if (command == "login")
            {
                //获取所有客户端在线信息到当前登录用户
                for (int i = 0; i < _userList.Count; i++)
                {
                    SendToClient(user, "login," + _userList[i].Name);
                }
                //把自己上线,发送给所有客户端
                for (int i = 0; i < _userList.Count; i++)
                {
                    if (user.Name != _userList[i].Name)
                    {
                        SendToClient(_userList[i], "login," + user.Name);
                    }
                }
            }
            else if (command == "logout")
            {
                for (int i = 0; i < _userList.Count; i++)
                {
                    if (_userList[i].Name != user.Name)
                    {
                        SendToClient(_userList[i], message);
                    }
                }
            }
        }


        /// <summary>
        /// 将用户移除
        /// </summary>
        /// <param name="user"></param>
        private void RemoveUser(Users user)
        {
            _userList.Remove(user);
            user.Close();
            Logs.AppendText(string.Format("当前连接用户数:{0}", _userList.Count));
        }




        /// <summary>
        /// 停止服务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Stop_OnClick(object sender, RoutedEventArgs e)
        {
            //发布通知
            Logs.AppendText("服务已停止!" + "\n");


            isNormalExit = true;
            for (int i = _userList.Count - 1; i >= 0; i--)
            {
                RemoveUser(_userList[i]);
            }


            if (_listener != null)
            {
                //停止服务
                _listener.Stop();
            }
            Start.IsEnabled = true;
        }


    }
}
0 0