亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? listener.cs

?? C#實現的網絡編程實驗聊天程序(含論文)
?? CS
字號:
?using System;
using System.Collections;
using System.Collections.Specialized;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace EasyChat_Server
{
    class Listener
    {

        #region 字段定義

        /// <summary>
        /// 服務器程序使用的端口,默認為8888
        /// </summary>
        private int _port = 8888;

        /// <summary>
        /// 接收數據緩沖區大小64K 
        /// </summary>
        private const int _maxPacket = 64 * 1024;

        /// <summary>
        /// 服務器端的監聽器
        /// </summary>
        private TcpListener _tcpl = null;

        /// <summary>
        /// 保存所有客戶端會話的哈希表
        /// </summary>
        private Hashtable _transmit_tb = new Hashtable();

        #endregion
        

        #region 服務器方法

        /// <summary>
        /// 關閉監聽器并釋放資源
        /// </summary>
        public void Close()
        {
            if (_tcpl != null)
            {
                _tcpl.Stop();
            }
            //關閉客戶端連接并清理資源
            if (_transmit_tb.Count != 0)
            {
                foreach (Socket session in _transmit_tb.Values)
                {
                    session.Shutdown(SocketShutdown.Both);
                }
                _transmit_tb.Clear();
                _transmit_tb = null;
            }
        }

        /// <summary>
        /// 配置監聽端口號
        /// </summary>
        public void GetConfig()
        {
            string portParam;
            Console.Write("請輸入監聽端口,直接回車則接受默認端口8888: ");
            portParam = Console.ReadLine();
            if (portParam != string.Empty)
            {
                if (!int.TryParse(portParam, out _port) || _port < 1023 || _port > 65535)
                {
                    _port = 8888;
                    Console.WriteLine("端口號不合法,默認端口號被接受!");
                }
            }
        }

        /// <summary>
        /// 序列化在線列表,向客戶端返回序列化后的字節數組
        /// </summary>
        /// <returns>序列化后的字節數組</returns>
        private byte[] SerializeOnlineList()
        {
            StringCollection onlineList = new StringCollection();
            foreach (object o in _transmit_tb.Keys)
            {
                onlineList.Add(o as string);
            }
            IFormatter format = new BinaryFormatter();
            MemoryStream stream = new MemoryStream();
            format.Serialize(stream, onlineList);
            byte[] ret = stream.ToArray();
            stream.Close();
            return ret;
        }

        /// <summary>
        /// 提取命令
        /// 格式為兩個一位整數拼接成的字符串。
        /// 第一位為0表示客戶機向服務器發送的命令,為1表示服務器向客戶機發送的命令。
        /// 第二位表示命令的含義,具體如下:
        /// "01"-離線
        /// "02"-請求在線列表
        /// "03"-請求對所有人閃屏振動
        /// "04"-請求對指定用戶閃屏振動
        /// "05"-請求廣播消息
        /// default-轉發給指定用戶
        /// </summary>
        /// <param name="s">要解析的包含命令的byte數組,只提取前兩個字節</param>
        /// <returns>拼接成的命令</returns>
        private string DecodingBytes(byte[] s)
        {
            return string.Concat(s[0].ToString(), s[1].ToString());
        }

        /// <summary>
        /// 線程執行體,轉發消息
        /// </summary>
        /// <param name="obj">傳遞給線程執行體的用戶名,用以與用戶通信</param>
        private void ThreadFunc(object obj)
        {
            //通過轉發表得到當前用戶套接字
            Socket clientSkt = _transmit_tb[obj] as Socket;
            while (true)
            {
                try
                {
                    //接受第一個數據包。
                    //僅有兩種情況,一為可以識別的命令格式,否則為要求轉發給指定用戶的用戶名。
                    //這里的實現不夠優雅,但不失為此簡單模型的一個解決之道。
                    byte[] _cmdBuff = new byte[128];
                    clientSkt.Receive(_cmdBuff);
                    string _cmd = DecodingBytes(_cmdBuff);
                    /// "01"-離線
                    /// "02"-請求在線列表
                    /// "03"-請求對所有人閃屏振動
                    /// "04"-請求對指定用戶閃屏振動
                    /// "05"-請求廣播消息
                    /// default-轉發給指定用戶
                    switch (_cmd)
                    {
                        case "01":
                            {
                                _transmit_tb.Remove(obj);
                                string svrlog = string.Format("[系統消息]用戶 {0} 在 {1} 已斷開... 當前在線人數: {2}\r\n\r\n", obj, DateTime.Now, _transmit_tb.Count);
                                Console.WriteLine(svrlog);
                                //向所有客戶機發送系統消息
                                foreach (DictionaryEntry de in _transmit_tb)
                                {
                                    string _clientName = de.Key as string;
                                    Socket _clientSkt = de.Value as Socket;
                                    _clientSkt.Send(Encoding.Unicode.GetBytes(svrlog));
                                }
                                Thread.CurrentThread.Abort();
                                break;
                            }
                        case "02":
                            {
                                byte[] onlineBuff = SerializeOnlineList();
                                //先發送響應信號,用于客戶機的判斷,"11"表示服務發給客戶機的更新在線列表的命令
                                clientSkt.Send(new byte[] { 1, 1 });
                                clientSkt.Send(onlineBuff);
                                break;
                            }
                        case "03":
                            {
                                string displayTxt = string.Format("[系統提示]用戶 {0} 向您發送了一個閃屏振動。\r\n\r\n", obj);
                                foreach (DictionaryEntry de in _transmit_tb)
                                {
                                    string _clientName = de.Key as string;
                                    Socket _clientSkt = de.Value as Socket;
                                    if (!_clientName.Equals(obj))
                                    {
                                        //先發送響應信號,用于客戶機的判斷,"12"表示服務發給客戶機的閃屏振動的命令
                                        _clientSkt.Send(new byte[] { 1, 2 });
                                        _clientSkt.Send(Encoding.Unicode.GetBytes(displayTxt));
                                    }
                                }
                                break;
                            }
                        case "04":
                            {
                                string _receiver = null;
                                byte[] _receiverBuff = new byte[128];
                                clientSkt.Receive(_receiverBuff);
                                _receiver = Encoding.Unicode.GetString(_receiverBuff).TrimEnd('\0');
                                string displayTxt = string.Format("[系統提示]用戶 {0} 向您發送了一個閃屏振動。\r\n\r\n", obj);
                                //通過轉發表查找接收方的套接字
                                if (_transmit_tb.ContainsKey(_receiver))
                                {
                                    Socket receiverSkt = _transmit_tb[_receiver] as Socket;
                                    receiverSkt.Send(new byte[] { 1, 2 });
                                    receiverSkt.Send(Encoding.Unicode.GetBytes(displayTxt));
                                }
                                else
                                {
                                    string sysMessage = string.Format("[系統消息]您剛才的閃屏振動沒有發送成功。\r\n可能原因:用戶 {0} 已離線或者網絡阻塞。\r\n\r\n", _receiver);
                                    clientSkt.Send(Encoding.Unicode.GetBytes(sysMessage));
                                }
                                break;
                            }
                        case "05":
                            {
                                byte[] _msgBuff = new byte[_maxPacket];
                                clientSkt.Receive(_msgBuff);
                                foreach (DictionaryEntry de in _transmit_tb)
                                {
                                    string _clientName = de.Key as string;
                                    Socket _clientSkt = de.Value as Socket;
                                    if (!_clientName.Equals(obj))
                                    {
                                        _clientSkt.Send(_msgBuff);
                                    }
                                }
                                break;
                            }
                        default:
                            {
                                //以上都不是則表明第一個包是接收方用戶名,繼續接受第二個消息正文數據包
                                string _receiver = Encoding.Unicode.GetString(_cmdBuff).TrimEnd('\0');
                                byte[] _packetBuff = new byte[_maxPacket];
                                clientSkt.Receive(_packetBuff);
                                if (_transmit_tb.ContainsKey(_receiver))
                                {
                                    //通過轉發表查找接收方的套接字
                                    Socket receiverSkt = _transmit_tb[_receiver] as Socket;
                                    receiverSkt.Send(_packetBuff);
                                }
                                else
                                {
                                    string sysMessage = string.Format("[系統消息]您剛才的內容沒有發送成功。\r\n可能原因:用戶 {0} 已離線或者網絡阻塞。\r\n\r\n", _receiver);
                                    clientSkt.Send(Encoding.Unicode.GetBytes(sysMessage));
                                }
                                break;
                            }
                    }
                }
                catch (SocketException)
                {
                    _transmit_tb.Remove(obj);
                    string svrlog = string.Format("[系統消息]用戶 {0} 的客戶端在 {1} 意外終止!當前在線人數:{2}\r\n\r\n", obj, DateTime.Now, _transmit_tb.Count);
                    Console.WriteLine(svrlog);
                    //向所有客戶機發送系統消息
                    foreach (DictionaryEntry de in _transmit_tb)
                    {
                        string _clientName = de.Key as string;
                        Socket _clientSkt = de.Value as Socket;
                        _clientSkt.Send(Encoding.Unicode.GetBytes(svrlog));
                    }
                    Console.WriteLine();
                    Thread.CurrentThread.Abort();
                }
            }
        }

        /// <summary>
        /// 啟動監聽,輪詢監聽客戶機請求并將客戶端套接字存入轉發表
        /// </summary>
        public void StartUp()
        {
            IPAddress _ip = Dns.GetHostAddresses(Dns.GetHostName())[0];
            _tcpl = new TcpListener(_ip, _port);
            _tcpl.Start();
            Console.WriteLine("服務器已啟動,正在監聽...\n");
            Console.WriteLine(string.Format("服務器IP:{0}\t端口號:{1}\n", _ip, _port));
            while (true)
            {
                byte[] packetBuff = new byte[_maxPacket];
                Socket newClient = _tcpl.AcceptSocket();
                newClient.Receive(packetBuff);
                string userName = Encoding.Unicode.GetString(packetBuff).TrimEnd('\0');
                //驗證是否為唯一用戶
                if (_transmit_tb.Count != 0 && _transmit_tb.ContainsKey(userName))
                {
                    newClient.Send(Encoding.Unicode.GetBytes("cmd::Failed"));
                    continue;
                }
                else
                {
                    newClient.Send(Encoding.Unicode.GetBytes("cmd::Successful"));
                }
                //將新連接加入轉發表并創建線程為其服務
                _transmit_tb.Add(userName, newClient);
                string svrlog = string.Format("[系統消息]新用戶 {0} 在 {1} 已連接... 當前在線人數: {2}\r\n\r\n", userName, DateTime.Now, _transmit_tb.Count);
                Console.WriteLine(svrlog);
                
                Thread clientThread = new Thread(new ParameterizedThreadStart(ThreadFunc));
                clientThread.Start(userName);
                //向所有客戶機發送系統消息
                foreach (DictionaryEntry de in _transmit_tb)
                {
                    string _clientName = de.Key as string;
                    Socket _clientSkt = de.Value as Socket;
                    if (!_clientName.Equals(userName))
                    {
                        _clientSkt.Send(Encoding.Unicode.GetBytes(svrlog));
                    }
                }
            }
        }

        #endregion
    }
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美日韩国产高清一区| 丰满岳乱妇一区二区三区| 在线观看精品一区| 亚洲一区二区视频| 欧美日韩精品三区| 日本女人一区二区三区| 日韩欧美电影在线| 国产精品123| 亚洲欧洲精品天堂一级| 日本国产一区二区| 三级影片在线观看欧美日韩一区二区| 在线不卡免费av| 韩国理伦片一区二区三区在线播放| 欧美xxxxx牲另类人与| 国产精品一二三区| 亚洲日本电影在线| 69堂亚洲精品首页| 国产高清不卡二三区| 亚洲欧美日韩久久精品| 欧美高清精品3d| 狠狠色丁香婷婷综合久久片| 国产拍欧美日韩视频二区| 97久久精品人人做人人爽50路| 亚洲一区二区三区四区在线观看| 91麻豆精品国产自产在线观看一区| 捆绑调教美女网站视频一区| 国产精品网站一区| 欧美电影影音先锋| 成人午夜视频在线观看| 亚洲一区二区视频在线观看| 日韩欧美高清dvd碟片| 不卡免费追剧大全电视剧网站| 亚洲第一久久影院| 国产人成亚洲第一网站在线播放| 在线观看91视频| 国产精品1024久久| 日韩中文字幕1| 国产精品久久久久久久久动漫 | 亚洲欧美日韩在线| 欧美一级久久久| 色综合久久久久综合99| 久久精品国产久精国产爱| 亚洲色图欧洲色图婷婷| 精品1区2区在线观看| 欧洲av在线精品| 成人精品gif动图一区| 蜜桃精品在线观看| 一个色综合网站| 国产精品三级电影| 日韩精品中文字幕一区二区三区 | 午夜精品久久久久久久久| 国产精品卡一卡二| 日韩欧美国产一区在线观看| 欧美在线制服丝袜| 99久久免费精品高清特色大片| 久久激情五月激情| 亚洲二区在线观看| 亚洲特黄一级片| 久久久亚洲国产美女国产盗摄 | 国产一区二区三区久久久| 亚洲电影一级黄| 亚洲日本丝袜连裤袜办公室| 国产日韩三级在线| 久久影院午夜片一区| 日韩亚洲欧美成人一区| 欧美日韩一区二区三区视频| 91免费视频网| 91亚洲精品一区二区乱码| 国产精品综合在线视频| 蜜臂av日日欢夜夜爽一区| 丝袜亚洲另类欧美综合| 亚洲最大成人综合| 亚洲最新视频在线观看| 一区二区在线观看视频| 亚洲久本草在线中文字幕| ●精品国产综合乱码久久久久| 国产欧美1区2区3区| 欧美极品少妇xxxxⅹ高跟鞋| 久久久久久9999| 精品福利在线导航| 国产欧美一区二区精品忘忧草| 2023国产精品| 亚洲国产成人午夜在线一区| 国产日韩亚洲欧美综合| 中文字幕亚洲在| 亚洲天堂中文字幕| 亚洲一区二区三区精品在线| 亚洲第一主播视频| 免费在线观看一区| 国产精品一区二区在线看| 成人午夜视频在线| 91国偷自产一区二区三区成为亚洲经典 | 成人av电影免费在线播放| 丁香六月综合激情| 91网站在线观看视频| 欧美做爰猛烈大尺度电影无法无天| 91麻豆免费观看| 欧美日韩在线三区| 日韩精品在线网站| 国产欧美一区二区三区网站| 亚洲三级免费观看| 五月天激情综合| 国内不卡的二区三区中文字幕| 丰满少妇久久久久久久| 日本精品一级二级| 欧美一区二区三区在线观看| 欧美精品一区二区三区很污很色的| 欧美激情综合网| 亚洲线精品一区二区三区| 另类欧美日韩国产在线| 不卡大黄网站免费看| 欧美午夜片在线观看| 精品国产乱码久久久久久蜜臀| 国产精品美女久久久久aⅴ| 亚洲国产综合91精品麻豆| 九九九久久久精品| 91在线视频免费观看| 91精品国产色综合久久| 欧美国产禁国产网站cc| 亚洲永久免费视频| 国产麻豆午夜三级精品| 一本色道综合亚洲| 日韩一区二区三区电影| 国产精品电影院| 秋霞电影一区二区| 成人听书哪个软件好| 在线播放91灌醉迷j高跟美女 | 成人av午夜影院| 在线成人av影院| 亚洲欧美日韩人成在线播放| 精品一区二区三区免费| 91国产免费观看| 久久久不卡网国产精品一区| 亚洲电影中文字幕在线观看| 粗大黑人巨茎大战欧美成人| 欧美一区二区三区日韩视频| 最新久久zyz资源站| 久久成人18免费观看| 欧美性受极品xxxx喷水| 中文欧美字幕免费| 狠狠色狠狠色综合日日91app| 欧美日韩国产综合草草| 亚洲欧美在线另类| 国产成人av一区二区三区在线| 538在线一区二区精品国产| 亚洲乱码国产乱码精品精小说| 国产成人在线网站| 精品国产乱码久久久久久夜甘婷婷| 亚洲国产精品久久不卡毛片| 99久久精品国产网站| 中文字幕欧美激情| 国产精品亚洲专一区二区三区| 91麻豆精品国产91久久久使用方法| 亚洲精选在线视频| 91亚洲国产成人精品一区二区三| 久久精品男人天堂av| 久久电影网站中文字幕| 777奇米四色成人影色区| 亚洲愉拍自拍另类高清精品| 日本韩国一区二区三区| 一区av在线播放| 在线观看日韩高清av| 亚洲精品免费在线| 91看片淫黄大片一级| 亚洲男帅同性gay1069| www.爱久久.com| 国产精品私房写真福利视频| 高清成人在线观看| 中文字幕av一区二区三区| 国产99一区视频免费| 国产欧美一区在线| av亚洲精华国产精华| 亚洲欧美成人一区二区三区| 色综合色狠狠综合色| 亚洲激情五月婷婷| 色婷婷国产精品综合在线观看| 亚洲人成伊人成综合网小说| 色噜噜久久综合| 亚洲午夜激情网站| 日韩欧美电影在线| 国产成人免费视频网站高清观看视频 | 国产在线精品一区在线观看麻豆| 日韩女优av电影在线观看| 国产一区二区三区电影在线观看| 久久久久久久综合色一本| 粉嫩av亚洲一区二区图片| 国产视频一区二区在线| 成人av网站在线观看| 亚洲综合视频在线| 欧美一区二区福利在线| 国产一区二区精品在线观看| 国产欧美日韩视频在线观看| 色伊人久久综合中文字幕| 日日噜噜夜夜狠狠视频欧美人| 91精品国产麻豆国产自产在线 | 日本aⅴ免费视频一区二区三区 | 国产欧美日韩一区二区三区在线观看| 成人一区二区三区视频在线观看| 亚洲精品视频在线看| 91精品蜜臀在线一区尤物|