当前位置:编程学习 > C#/ASP.NET >>

求助 socket异常 1054

namespace T_QQ
{
    class T_VOID
    {
        #region  定义字段  
        private int T_port = 9999;    
        private const int T_maxPack = 128 * 1024; 
        private TcpListener T_lister=null;
        private Hashtable T_Hash = new Hashtable();
        #endregion
        public void T_Close()
        {
            if (T_lister != null)
            {
                T_lister.Stop();
            }
            if (T_Hash.Count != 0)
            {
                foreach (Socket SK in T_Hash.Values)
                {
                    SK.Shutdown(SocketShutdown.Both);
                }
                T_Hash.Clear();
                T_Hash = null;
            }
        }
        /// <summary>
        /// 端口设定
        /// </summary>
        public void GetConfig()
        {
            string PortPAram;
            Console.Write("请输入监听端口,直接回车则接受默认端口9999");
            PortPAram = Console.ReadLine();
            if (PortPAram != string.Empty)
            {
                if (!int.TryParse(PortPAram ,out T_port) || T_port < 1023 || T_port > 65535)
                {
                    T_port = 8888;
                    Console.Write("端口不合法,启用默认端口");
                }
            }
            
        }
        /// <summary>
        /// 序列化
        /// </summary>
        /// <returns></returns>
        private byte[] Ser_onlie_list()
        {

            StringCollection Onlielist = new StringCollection();
            foreach (object o in T_Hash.Keys)
            {
                Onlielist.Add(o as string);
            }
            BinaryFormatter xxx = new BinaryFormatter();
            MemoryStream stream = new MemoryStream();
            xxx.Serialize(stream, Onlielist);
            byte[] T_byte = stream.ToArray();
            stream.Close();
            return T_byte;
        }
        /// <summary>
        /// 提取命令
        /// 格式为两个一位整数拼接成的字符串。
        /// 第一位为0表示客户机向服务器发送的命令,为1表示服务器向客户机发送的命令。
        /// 第二位表示命令的含义,具体如下:
        /// "01"-离线
        /// "02"-请求在线列表
        /// "03"-请求对所有人闪屏振动
        /// "04"-请求对指定用户闪屏振动
        /// "05"-请求广播消息
        /// default-转发给指定用户
        /// </summary>
        /// <param name="s">要解析的包含命令的byte数组,只提取前两个字节</param>
        /// <returns>拼接成的命令</returns>
        private string Decoding(byte[] s)
        {
            return string.Concat(s[0].ToString(),s[1].ToString());
        }
        private void T_thread(object obj)
        {
            Socket client_sock = T_Hash[obj] as Socket;
            try
            {
                while (true)
                {
                    byte[] buf = new byte[128];
                    client_sock.Receive(buf);
                    string _cmd = Decoding(buf);
                    switch (_cmd)
                    {
                        case "01":
                            {
                                T_Hash.Remove(obj);
                                string s_man = string.Format("[系统消息]用户 {0} 在 {1} 已断开... 当前在线人数: {2}\r\n\r\n", obj, DateTime.Now, T_Hash.Count);
                                Console.WriteLine(s_man);
                                //foreach (DictionaryEntry de in T_Hash)
                                //{
                                //    string clientName = de.Key as string;
                                //    Socket _clientsk = de.Value as Socket;
                                //    _clientsk.Send(Encoding.Unicode.GetBytes(s_man));
                                //}
                                Thread.CurrentThread.Abort();
                                break;
                            }
                        case "02":
                            {
                                byte[] onlinbuf = Ser_onlie_list();
                                client_sock.Send(new byte[] {1,1});
                                client_sock.Send(onlinbuf);
                                break;
                            }
                        case "03":
                            {
                                string shine = string.Format("[系统提示]用户 {0} 向您发送了一个闪屏振动。\r\n\r\n", obj);
                                foreach (DictionaryEntry de in T_Hash)
                                {
                                    string _clientName = de.Key as string;
                                    Socket _clientSkt = de.Value as Socket;
                                    if (!_clientName.Equals(obj))
                                    {
                                        _clientSkt.Send(new byte[] { 1, 2 });
                                        _clientSkt.Send(Encoding.Unicode.GetBytes(shine));
                                    }

                                }
                                break;
                            }
                        case "04":
                            {
                                string _receive = null;
                                byte[] _reb_buf = new byte[128];
                                client_sock.Receive(_reb_buf);
                                _receive = Encoding.Unicode.GetString(_reb_buf);
                                string shine = string.Format("[系统提示]用户 {0} 向您发送了一个闪屏振动。\r\n\r\n", obj);
                                if (T_Hash.ContainsKey(_receive))
                                {
                                    Socket recesock = T_Hash[_receive] as Socket;
                                    recesock.Send(new byte[] { 1, 2 });
                                    recesock.Send(Encoding.Unicode.GetBytes(shine));
                                }
                                else
                                {
                                    string mess_wrong = string.Format("[系统消息]您刚才的闪屏振动没有发送成功。\r\n可能原因:用户 {0} 已离线或者网络阻塞。\r\n\r\n", _receive);
                                    client_sock.Send(Encoding.Unicode.GetBytes(mess_wrong));
                                }
                                break;
                            }
                        case "05":
                            {
                                byte[] allbuf = new byte[T_maxPack];
                                client_sock.Receive(allbuf);
                                foreach (DictionaryEntry de in T_Hash)
                                {
                                    string _clientName = de.Key as string;
                                    Socket _clientskt = de.Value as Socket;
                                    if (!_clientName.Equals(obj))
                                    {
                                        _clientskt.Send(allbuf);
                                    }
                                 
                                    
                                }
                                  break;
                            }
                        default:
                            {
                                string receive = Encoding.Unicode.GetString(buf).TrimEnd('\0');
                                byte[]  _Pack=new byte[T_maxPack];
                                client_sock.Receive(_Pack);
                                if (T_Hash.ContainsKey(receive))
                                {
                                    Socket sk = T_Hash[receive] as Socket;
                                    sk.Send(_Pack);
                                }
                                else
                                {
                                    string mess = string.Format("[系统消息]您刚才的内容没有发送成功。\r\n可能原因:用户 {0} 已离线或者网络阻塞。\r\n\r\n", receive);
                                    client_sock.Send(Encoding.Unicode.GetBytes(mess));
                                }
                                break;
                            }

                    }

                }
            }
            catch (SocketException E)
            {
                T_Hash.Remove(obj);
                string sysmessage = string.Format("[系统消息]用户 {0} 的客户端在 {1} 离线!当前在线人数:{2}\r\n\r\n", obj, DateTime.Now,T_Hash.Count);
                Console.WriteLine(sysmessage+E.Message+E.TargetSite+E.NativeErrorCode);
                Console.WriteLine();
                Thread.CurrentThread.Abort();
            }
        }
        public void T_StartUp()
        {
            IPAddress T_IP=Dns.GetHostAddresses(Dns.GetHostName())[0];
            T_lister = new  TcpListener(T_IP, T_port);
            T_lister.Start();
            Console.WriteLine("服务器已监听。。。\n");
            Console.WriteLine(string.Format("服务器IP:{0}\t端口号:{1}\n", T_IP, T_port));
            while (true)
            {
                byte[] packbuf=new  byte[T_maxPack];
                Socket newClient = T_lister.AcceptSocket();
                newClient.Receive(packbuf);
                string UserName = Encoding.Unicode.GetString(packbuf).TrimEnd('\0');
                if(T_Hash.Count!=0 && T_Hash.ContainsKey(UserName))
                {
                    newClient.Send(Encoding.Unicode.GetBytes("cmd::Failed"));
                    continue;
                }
                else
                {
                    newClient.Send(Encoding.Unicode.GetBytes("cmd::Successful"));
                }
                T_Hash.Add(UserName,newClient);
                string sysmessage=string.Format("[系统消息]新用户 {0} 在 {1} 已连接... 当前在线人数: {2}\r\n\r\n",UserName,DateTime.Now,T_Hash.Count);
                Console.WriteLine(sysmessage);
                Thread cliendthred = new Thread(new ParameterizedThreadStart(T_thread));
                cliendthred.Start(UserName);
            }

        }
        
    }
}

    --------------------编程问答-------------------- 帮顶把
啥说明都没有 --------------------编程问答-------------------- case "05":  那里    主机强迫失去连接
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,