借朋友的号给大家散分
namespace Proxy_Server
{
    public class Listener
    {
     
        /// <summary>
        /// 启动监听,轮询监听客户机请求并将客户端套接字存入转发表
        /// </summary>
        public void StartProxy()
        {
         ......................................
                  .....................
            while (true)
            {
                Thread.Sleep(5);
                Socket newClient = _tcpl.AcceptSocket();//本地TcpListener 接受新的请求                 IPAddress remote_ip = ((System.Net.IPEndPoint)newClient.RemoteEndPoint).Address;//获取客户连接IP
                int remote_port = ((System.Net.IPEndPoint)newClient.RemoteEndPoint).Port;
                string ClientId = remote_ip.ToString() + ":" + remote_port;
                if (_transmit_tb.Count != 0 && _transmit_tb.ContainsKey(ClientId))
                {
                    Console.WriteLine("客户端IP:" + ClientId + "已存在,踢出该连接..\n");
                    Console.WriteLine();
                    continue;
                }
                else
                {
                    Connect(ClientId);//创建代理与游戏服务器连接
                    if (_tcpc == null)
                    {
                        Console.WriteLine("与游戏服务器连接失败...\n");
                        Console.WriteLine();
                        _tcpc.Close();
                        continue;
                    }
                    //将连接保存到哈希表
                  //  NetworkStream netstream = _tcpc.GetStream();
                    _receive_tb.Add(ClientId, _tcpc);
                    _transmit_tb.Add(ClientId, newClient);                    //-----------------------
                    string svrlog = string.Format("新客户端 {0} 在 {1} 已代理... 当前在线人数: {2}\r\n\r\n", ClientId, DateTime.Now, _transmit_tb.Count);
                    Console.WriteLine(svrlog);
                    Console.WriteLine();
                    //------------------------
                    //创建新线程服务
                    Thread clientThreadSend = new Thread(new ParameterizedThreadStart(ThreadFuncSend));
                    clientThreadSend.Start(ClientId);
                    Thread clientThreadRead = new Thread(new ParameterizedThreadStart(ThreadFuncRead));
                    clientThreadRead.Start(ClientId);
                }
            }
        }        #endregion        /// <summary>
        /// 创建于游戏服务器连接
        /// </summary>
        /// <param name="remote_ip"></param>
        /// <returns></returns>
        public TcpClient Connect(string remote_ip)
        {
            try
            {
                IPAddress _ipAddr = IPAddress.Parse(SrvInfo.gamesrvip);
                int _Port = int.Parse(SrvInfo.gamesrvport);
                _tcpc = new TcpClient();
                _tcpc.Connect(_ipAddr, _Port);//连接到服务
                string svrlog = string.Format("服务器新建立{0}与{1}的连接...\n", remote_ip.ToString(), _ipAddr.ToString());
                Console.WriteLine(svrlog);
                Console.WriteLine();
            }
            catch (Exception)
            {
                return null;
            }
            return _tcpc;
        }        /// <summary>
        /// 从客户端获取数据发送给游戏服务器
        /// </summary>
        /// <param name="obj"></param>
        public void ThreadFuncSend(object obj)
        {
            //通过转发表得到当前用户套接字
            Socket clientSkt = _transmit_tb[obj] as Socket;
            TcpClient myclient = _receive_tb[obj] as TcpClient;
            NetworkStream netstream = myclient.GetStream();
           // NetworkStream netstream = _receive_tb[obj] as NetworkStream;            byte[] buffer = new byte[_maxPacket];
            int recvlen = 0;
            while (true)
            {
                   try
                    {
                        recvlen = clientSkt.Receive(buffer); //从客户端获取数据
                        if (recvlen > 0)
                        {
                            netstream.Write(buffer, 0, recvlen); //发送给游戏服务器
                            netstream.Flush();
                        }
                        buffer = new byte[_maxPacket]; //清空
                    }
                    catch (SocketException ex)
                    {
                        WriteData.WriteLine(ex.Message);
                        Close(clientSkt, netstream, myclient, obj);
                        string svrlog = string.Format("Send - IP:{0} 在 {1} 断开与代理连接! 当前连接数:{2}\r\n\r\n", obj, DateTime.Now, _transmit_tb.Count);
                        Console.WriteLine(svrlog);
                        Console.WriteLine();
                        Thread.CurrentThread.Abort();
                    }
                    finally { }
                    //打印客户发送的异常数据
                    if (recvlen > 1024 || recvlen < 10)
                    {
                        if (recvlen > 0)
                        {
                            string str = string.Empty;
                            for (int i = 0; i < recvlen; i++)
                            {
                                str += string.Format("{0:X}", buffer[i]);
                            }
                            WriteData.WriteLine(obj + ": " + str);
                        }
                    }                    Thread.Sleep(5);
            }
        }        /// <summary>
        /// 从游戏服务器读取数据发送给客户端
        /// </summary>
        /// <param name="obj"></param>
        public void ThreadFuncRead(object obj)
        {
            //通过转发表得到当前用户套接字
            Socket clientSkt = _transmit_tb[obj] as Socket;
            TcpClient myclient = _receive_tb[obj] as TcpClient;
            NetworkStream netstream = myclient.GetStream();
            //NetworkStream netstream = _receive_tb[obj] as NetworkStream;            byte[] buffer = new byte[_maxPacket];
            int recvlen = 0;
            while (true)
            {
                    try
                    {                        recvlen = netstream.Read(buffer, 0, buffer.Length); //从主服务器获取数据
                        if (recvlen > 0)
                        {
                            clientSkt.Send(buffer, recvlen, SocketFlags.None);//发送给客户端
                        }
                        buffer = new byte[_maxPacket];//清空
                    }
                    catch (SocketException ex)
                    {
                        WriteData.WriteLine(ex.Message);
                        Close(clientSkt, netstream, myclient, obj);
                        string svrlog = string.Format("Read - 客户端:{0}的代理与游戏服务器断开! {1} \r\n\r\n", obj, DateTime.Now);
                        Console.WriteLine(svrlog);
                        Console.WriteLine();
                        Thread.CurrentThread.Abort();
                    }
                    finally { }
                    Thread.Sleep(5);
            }
        }        /// <summary>
        /// 释放
        /// </summary>
        public void Close(Socket clientSkt, NetworkStream netstream, TcpClient myclient, object obj)
        {
            //clientSkt.Shutdown(SocketShutdown.Both);
            //myclient.Client.Shutdown(SocketShutdown.Both);
            if (clientSkt != null)
            {
                clientSkt.Close();
            }
            if (netstream != null)
            {
                netstream.Close();
            }
            if (myclient != null)
            {
                myclient.Close();
                myclient.Client.Close();
            }
            _transmit_tb.Remove(obj); //从哈希表移除
            _receive_tb.Remove(obj);
        }    }
}现在的问题是不稳定,每个客户端连接,我开两个线程为其服务,一个线程负责接收客户端信息发送给游戏服务端,另外一个线程负责接收游戏服务器数据发送给客户端!现在释放有个问题,如果有一个方法释放了Socket和cpClient,另一个方法的Read或Receive就会报错!还有很多特殊情况等!
c#的socket是不安全的,请高人优化下,程序如何修改才能稳定!

解决方案 »

  1.   

    在线等!没有人看热闹吗?部分代码我删掉了,CSDN不允许发太长!
    我发的是关键位置的!
    recvlen = clientSkt.Receive(buffer); //从客户端获取数据
      recvlen = netstream.Read(buffer, 0, buffer.Length); //从主服务器获取数据
    这两个位置不稳定不管我释放不释放都不稳定!
      

  2.   

    回复:nidezhousuhui不是很熟悉, 我以为这样做处理效率更高,为每个客户建立单独的线程!您能说详细点吗?
      

  3.   

    什么叫做“不稳定,还有很多特殊情况等”?看不明白。如果发现什么bug,分析其原因。如果是网络中断等等,很自然地你的代理也就自动中断了了事(就好象服务或者客户端中断一样),你还能怎样?你的代理的设计是要看原来的客户端和服务端的协议设计如何,如果人家原来没有特别设计网络中断时的具体动作协议,那么它当然就要做的跟原来的一模一样了。