我BS服务器 开启Socket监听开启多线程多个客户端连接之后为什么只能接受到最后一个连接上的 客户端数据
其他数据发哪了?什么情况
有解答的吗?发送连接上的其他客户端都可以
但就是没接受上来我线程不好Socket也是才接触的帮忙解答下(顺便说下 线程池怎么用好些
其实我之前是都可以接受到的
改线程池 又重启IIS 换回多线程 不用线程池 就这样了 不知道什么原因)

解决方案 »

  1.   

    目前的情况就是 只能接受最后一个连接上的客户端发送过来的信息
    其他已经连接的客户端信息接受不到
    但服务端 可以 发送数据过去
    什么原因啊?
    我程序 线程的问题 还是客户端?
    (我客户端是硬件的gprs也不能保证 那个就没问题
    所以查起BUG来 比较纠结)
      

  2.   

    可以 给你看 开启的 代码        private static Socket mySocket = null;
            private static IPAddress ipa = null;//把IP字符串形式转换为IP实例形式
                foreach (IPAddress item in Dns.GetHostEntry("").AddressList)
                {
                    if (System.Text.RegularExpressions.Regex.IsMatch(item.ToString(),
                        Constants.RegularHttp))
                    {
                        ipa = item;
                        break;
                    }
                }//监听端口2020   
                TcpListener mylistenter = new TcpListener(ipa, Constants.IPPort);
                //ThreadPool.SetMinThreads(10, 10);
                //ThreadPool.SetMaxThreads(100, 100);
                try
                {
                    mylistenter.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                    mylistenter.Start();
                    FileConfig.WritetFile(Constants.FileListenter + mylistenter.LocalEndpoint.ToString());
                    //int a, b;
                    //等待处理接入连接请求
                    while (true)
                    {
                        Thread.Sleep(100);
                        mySocket = mylistenter.AcceptSocket();
                        listSocket.Add(mySocket);
                        //构造新实例
                        DoWork.InitDoWork(mySocket);
                        Thread mythread = new Thread(new ThreadStart(DoWork.ReceiveMethod));
                        mythread.Start();
                        /*ThreadPool.QueueUserWorkItem(o =>
                        {
                            Thread.Sleep(100);
                            a = 0; b = 0;
                            ThreadPool.GetAvailableThreads(out a, out b);
                            FileConfig.WritetFile(string.Format(Constants.FileClient, a, b,
                                Thread.CurrentThread.ManagedThreadId, DateTime.Now, mySocket.RemoteEndPoint));
                            DoWork.ReceiveMethod();
                        });*/
                    }
                }
                catch (Exception ex)
                {
                    FileConfig.WritetFile(Constants.FileException + ex.ToString());
                }
                finally
                { }
    我去吃饭了 一会来啊
      

  3.   

    可以 给你看 开启的 代码        private static Socket mySocket = null;
            private static IPAddress ipa = null;//把IP字符串形式转换为IP实例形式
                foreach (IPAddress item in Dns.GetHostEntry("").AddressList)
                {
                    if (System.Text.RegularExpressions.Regex.IsMatch(item.ToString(),
                        Constants.RegularHttp))
                    {
                        ipa = item;
                        break;
                    }
                }//监听端口2020   
                TcpListener mylistenter = new TcpListener(ipa, Constants.IPPort);
                //ThreadPool.SetMinThreads(10, 10);
                //ThreadPool.SetMaxThreads(100, 100);
                try
                {
                    mylistenter.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                    mylistenter.Start();
                    FileConfig.WritetFile(Constants.FileListenter + mylistenter.LocalEndpoint.ToString());
                    //int a, b;
                    //等待处理接入连接请求
                    while (true)
                    {
                        Thread.Sleep(100);
                        mySocket = mylistenter.AcceptSocket();
                        listSocket.Add(mySocket);
                        //构造新实例
                        DoWork.InitDoWork(mySocket);
                        Thread mythread = new Thread(new ThreadStart(DoWork.ReceiveMethod));
                        mythread.Start();
                        /*ThreadPool.QueueUserWorkItem(o =>
                        {
                            Thread.Sleep(100);
                            a = 0; b = 0;
                            ThreadPool.GetAvailableThreads(out a, out b);
                            FileConfig.WritetFile(string.Format(Constants.FileClient, a, b,
                                Thread.CurrentThread.ManagedThreadId, DateTime.Now, mySocket.RemoteEndPoint));
                            DoWork.ReceiveMethod();
                        });*/
                    }
                }
                catch (Exception ex)
                {
                    FileConfig.WritetFile(Constants.FileException + ex.ToString());
                }
                finally
                { }
    我去吃饭了 一会来啊
      

  4.   

    没人会了???偌大的CSDN=。=!不要沉啊
      

  5.   

    恩自己写的 静态类
    用于连接后 while()里面处理接收到的数据
    我原来都是好的 就是换线程池后 不晓得什么情况
    现在看来好像变成单线程了 我去
    但客户端都是连接上来的
    服务端 可以发送数据
      

  6.   

    如果
    Thread mythread = new Thread(new ThreadStart(DoWork.ReceiveMethod));
    mythread.Start();
    这样是正常的,就改成这样
    ThreadPool.QueueUserWorkItem(v1 => DoWork.ReceiveMethod());
    再有问题吧 DoWork 内容发上来吧
      

  7.   

    这个是线程池 我也用过的 set min max....好吧 我再试下
    谢谢
      

  8.   

    再看下
    ThreadPool.SetMinThreads(10, 10);
    ThreadPool.SetMaxThreads(100, 100);
    这个没问题吧
    还是不行 像单线程的 只有最后连接的数据可以上传
    我把ReceiveMethod的代码 贴出来吧            //接收客户端消息
                int length = 0;
                byte[] byteData = null;//new byte[1024];
                string request = string.Empty;
                string DataHeader = string.Empty;
                string DataTrunk = string.Empty;
                Flag = true;
                while (true)
                {
                    Thread.Sleep(100);
                    length = socket.Available;
                    if (socket.Connected && length > 16)
                    {
                        try
                        {
                            byteData = new byte[length];
                            //将从客户端流读取的数据保存到字符串request中
                            socket.Receive(byteData);
                            request = System.Text.UTF8Encoding.UTF8.GetString(byteData);
                            DataHeader = string.Empty;
                            DataTrunk = string.Empty;
                            ReceiveData(request, ref DataHeader, ref DataTrunk);
                            FileConfig.WritetFile(string.Format(Constants.FileNewData,
                                DataHeader, DataTrunk, request.Length, request));
                        }
                        catch (Exception ex)
                        {
                            FileConfig.WritetFile(socket.RemoteEndPoint.ToString() + Constants.FileColseException +
                                ex.ToString());
                            /*if (listSocket.Contains(socket))
                            {
                                listSocket.Remove(socket);
                            }
                            socket.Shutdown(SocketShutdown.Both);
                            socket.Close();*/
                        }
                        finally
                        { }
                    }
                }
    应该就这些了 我开启的 线程和Socket连接 我还没处理关闭的呢
    有问题...唉 在琢磨呢
      

  9.   

    ThreadPool.SetMinThreads(10, 10);
    ThreadPool.SetMaxThreads(100, 100);
    这两个不要去动开启 代码
    foreach (IPAddress item in Dns.GetHostEntry("").AddressList)
    {
        if (System.Text.RegularExpressions.Regex.IsMatch(item.ToString(),
            Constants.RegularHttp))
        {
            ipa = item;
            break;
        }
    }//监听端口2020   
    TcpListener mylistenter = new TcpListener(ipa, Constants.IPPort);
    //ThreadPool.SetMinThreads(10, 10);
    //ThreadPool.SetMaxThreads(100, 100);
    try
    {
        mylistenter.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        mylistenter.Start();
        FileConfig.WritetFile(Constants.FileListenter + mylistenter.LocalEndpoint.ToString());
        //int a, b;
        //等待处理接入连接请求
        while (true)
        {
            mySocket = mylistenter.AcceptSocket();
            ThreadPool.QueueUserWorkItem(DoWork.ReceiveMethod, mySocket);
        }
    }
    catch (Exception ex)
    {
        FileConfig.WritetFile(Constants.FileException + ex.ToString());
    }
    finally
    { }
    ReceiveMethod 代码
    private static void ReceiveMethod(object state)
    {
        Socket socket = (Socket)state;
        int length = 0;
        byte[] byteData = null;//new byte[1024];
        string request = string.Empty;
        string DataHeader = string.Empty;
        string DataTrunk = string.Empty;
        bool Flag = true;
        while (true)
        {
            Thread.Sleep(100);
            length = socket.Available;
            if (socket.Connected && length > 16)
            {
                try
                {
                    byteData = new byte[length];
                    //将从客户端流读取的数据保存到字符串request中
                    socket.Receive(byteData);
                    request = System.Text.UTF8Encoding.UTF8.GetString(byteData);
                    DataHeader = string.Empty;
                    DataTrunk = string.Empty;
                    ReceiveData(request, ref DataHeader, ref DataTrunk);
                    FileConfig.WritetFile(string.Format(Constants.FileNewData,
                        DataHeader, DataTrunk, request.Length, request));
                }
                catch (Exception ex)
                {
                    FileConfig.WritetFile(socket.RemoteEndPoint.ToString() + Constants.FileColseException +
                        ex.ToString());
                    /*if (listSocket.Contains(socket))
                    {
                        listSocket.Remove(socket);
                    }
                    socket.Shutdown(SocketShutdown.Both);
                    socket.Close();*/
                }
                finally
                { }
            }
        }
    }
      

  10.   

    学习啊
    学习等待cao老大批判,不是北大青鸟的学生,竟然还用这个阻塞模式啊
      

  11.   

    ReceiveData 这个方法是不是把客户端发送的数据记入队列? 方法内容贴上来
      

  12.   

    ReceiveData这个其实是 对接收到的数据
    request = System.Text.UTF8Encoding.UTF8.GetString(byteData);
    一个解析 进库
    代码可以贴 可能有点乱
    private static void ReceiveData(string data, ref string DataHeader, ref string DataTrunk)
            {
                //管理器与服务器开始连接
                TempIP = socket.RemoteEndPoint.ToString();
                //
                Mayam.Model.T_USER_DATAH model = new Model.T_USER_DATAH();
                model.EquipmentID = EquipmentID;
                model.Code = subid;
                model.Data = string.Empty;
                model.OldData = data;
                model.IPAddress = TempIP;
                control.Add(model);
                if (!RelayState(model))
                {
                    //数据头
                    DataHeader = data.Substring(0, 16);
                    //数据枝干
                    DataTrunk = data.Substring(16, data.Length - 16);
                    if (DataHeader.ToUpper().StartsWith(Constants.DataStart))
                    {
                        temp_sub = string.Empty;
                        EquipmentID = int.Parse(DataHeader.Substring(12, 4));
                        //
                        Mayam.Model.T_USER_Temp temp = temp_control.GetModel(EquipmentID.ToString());
                        #region 是否为心跳包
                        if (DataHeader.Substring(4, 2).Equals(Constants.DataStandard))
                        {
                            //截取数据包 默认为一包 可包含N组数据解析
                            foreach (string item in
                                DataTrunk.Replace(Constants.DataHeaderTail, Constants.DataExcision)
                                .Split(Constants.DataSeparator))
                            {
                                if (item.Length > 4)
                                {
                                    subid = GetClientID(item.Substring(2, 4));
                                    temp_sub += string.Format(Constants.DataSubsite, subid);
                                    //协议主方法                         管理器ID 终端IP端口 子站号
                                    AgreementAnalysis.MainMethod(item, EquipmentID, TempIP, subid);
                                    socket.Send(UTF8Encoding.UTF8.GetBytes(Constants.DataSuccess));
                                }
                            }
                        }
                        else
                        {
                            //心跳包 不予解析
                            socket.Send(UTF8Encoding.UTF8.GetBytes(Constants.DataXTB));
                        }
                        #endregion
                        lock (lockEdit)
                        {
                            temp.IPAddress = TempIP;
                            temp.Substation = temp_sub.TrimEnd(Constants.DataSeparator);
                            temp_control.Edit(temp);
                        }
                        if (Flag)
                        {
                            InitRelay();
                            Flag = false;
                        }
                    }
                    else
                    {
                        //数据头格式不对 不予解析
                        socket.Send(UTF8Encoding.UTF8.GetBytes(data));
                    }
                }
            }
      

  13.   

    按我12楼的代码,你先调试看下 ReceiveMethod 方法的执行次数和客户端请求的次数是否一致? 如果一致,哪里使你觉得只有最后一次收到了?
      

  14.   

    ReceiveMethod 方法的有没少执行? control 里的数据还是其他数据找不到了?
      

  15.   

    //ReceiveData(request, ref DataHeader, ref DataTrunk);
    我现在把处理数据的这个方法屏蔽了 再试试看
    还有socket.Available要放到变量里
    要不在线程里 不晓得什么时候又变为 0 了
      

  16.   

    socket.Available 这个可以不用,我想知道的是你说的接收不到体现在哪,程序中建立的数据结构里没有数据?
      

  17.   

    没有到接受函数中
    也就是
    socket.Receive(byteData);
    request = System.Text.UTF8Encoding.UTF8.GetString(byteData);
    这里 就没进来
      

  18.   

    我把上周程序还原上去了
    貌似还是不行
    我端口没重置好
    打开的Socket监听 不知道怎么关
    我本机server2003里
    可以直接关闭WebDev.WebServer40.exe这个进程
    开启的端口就关了但服务器是server2008的 找不到关闭的地方...
    也总不能老重启服务器吧...
      

  19.   

    多线程不熟,那就先用单线程来实现,后面再优化//ThreadPool.SetMinThreads(10, 10);
    //ThreadPool.SetMaxThreads(100, 100);
    其实随意设置它们并不好,因为你不知道客户机器的硬件配置。线程池是托管的,你不用去关心最大数和最小数,不要同时去开启太多的线程,同时保证线程能正常退出就行了
      

  20.   

    所以我不知道 怎么关闭在IIS的网站
    开启的Socket监听...
    WF程序的关闭所有就可以了
      

  21.   

    我程序是依托在IIS中的 开启后不知道怎么关闭端口了
    所以就 重启IIS=。=!
    有好方法吗?指导下
      

  22.   

    做socket程序,你还要在iis中写,有点无语,为什么不直接写一个winform
      

  23.   

    你放wf中 如何在BS上 发送指令到 客户端
    别告诉我再进程间 通讯
    我现在已经实现了
    只是感觉有点不稳定 开启的端口会断开
      

  24.   

    private static Socket mySocket = null;mySocket = mylistenter.AcceptSocket();
    listSocket.Add(mySocket);
    我理解就是listSocket应该是一个socket集合作为连接池的吧?
    但是从这几行代码上看到,实际上你的listSocket里面所有的socket都是最后一个客户端连上的socket,Socket是服务端和客户端之间的通讯通道,如果有N个客户端连上了,服务端应该有N个socket实例的,服务端和每个客户端通讯的socket实例是不同的,大概看了下代码,您服务端和客户端的通讯是否仅仅只是最后一次连接的客户端是有效的?
      

  25.   

    但不是这个问题 listSocket
    只是用于存储连接上的socket
    主要用于发送指令的时候找到对应的socket
    对于接受没有具体作用的
    应该不是这个问题
    但很奇怪之前是好的...
    怀疑是不是server2008不熟悉
    或IIS7.0不熟悉 导致的
      

  26.   

      mylistenter.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        mylistenter.Start();
        FileConfig.WritetFile(Constants.FileListenter + mylistenter.LocalEndpoint.ToString());
        //int a, b;
        //等待处理接入连接请求
        while (true)
        {
            Socket  mySocket = mylistenter.AcceptSocket();
            ThreadPool.QueueUserWorkItem(DoWork.ReceiveMethod, mySocket);
        }这样试试呢?
      

  27.   

    不行 一样的 之前也是这样 
    AcceptSocket();等待连接
    开线程 一样是进副本
      

  28.   

    一直没搞明白select模型的优点。使用阻塞模型+线程池不是可以达到同样的效果吗?
      

  29.   

    楼主的代码组织方式,还停留在客户端、单线程环境下。  服务器端用这种逻辑写出来的代码,问题很多。往往是1个或少数几个连接没有问题,连接数一多,问题就会集中爆发出来。 
    建议:
    服务器端坚决 不能用阻塞模式。(需要用begin开头的函数,坚决制止sleep函数)
    线程池不用操心,底层已经做了。
    管理好缓冲区
    一般都需要添加Session管理逻辑。
      

  30.   

    问下 我之前是不是搞线程通信的
    现在BS上有这个需求 还望指出
    我在看http://www.cnblogs.com/kingmoon/archive/2011/04/29/2032452.html
    Socket的异步通信 之前的是同步通信 我才知道=。=!
      

  31.   

    这位兄台 我在网上找了点东西
    用起来 怪怪的 上的链接研究了下
    没有加上线程池 接受数据也是有些问题
    要么是连接接受一次后断
    改过代码 不断了 但只接受一次 好像没有持续监听接受的意思...
    还望指导下 线程池+Socket异步通信 监听接受
      

  32.   

    给你看看我写的一段监听代码,应当对你有所帮助
    class listener
        {
            public TcpListener myListener;
            public int port = 808;
            public MainForm mainform = null;
            public bool isabort=false;        public void StartListen()
            {
                try
                {
                    myListener = new TcpListener(port);
                    myListener.Start();
                    mainform.MessageShow("服务已启动");
                }
                catch (Exception e)
                {
                    mainform.MessageShow(e.ToString());
                    return;
                }
                bool sdif=ThreadPool.SetMaxThreads(100, 100);//设置线程池线程数量
                //int sds, dsd;
                //ThreadPool.GetMaxThreads(out sds, out dsd);
                while (true)
                {
                    Socket mySocket = null;
                    if (myListener != null && myListener.Pending())
                    {
                        try
                        {
                            //接受新连接
                            mySocket = myListener.AcceptSocket();
                        }
                        catch (Exception zxz)
                        {
                            mainform.MessageShow(zxz.ToString());
                        }
                    }
                    //Thread.Sleep(5);
                    if (isabort)
                        break;
                    if (mySocket == null)
                        continue;
                    mainform.MessageShow("..." + mySocket.RemoteEndPoint.ToString() + "...Connecting......");
                    ThreadPool.QueueUserWorkItem(ReceiveDataFromSocket, mySocket);
                }
            }        private void ReceiveDataFromSocket(object obj)
            {
                Socket mySocket = (Socket)obj;
                Byte[] bReceive = new Byte[1024 * 1024];
                int i = 0;
                try
                {
                    //Thread.Sleep(4000);
                    i = mySocket.Receive(bReceive);
                }
                catch (Exception zxz)
                {
                    Thread.CurrentThread.Abort();
                    return;
                }
                string sBuffer = Encoding.GetEncoding("gb2312").GetString(bReceive, 0, i);
                .
    ........
            }    }
      

  33.   

    貌似上面的 也不行
    说下吧 我现在写了
    1.仿WF多线程版本 Socket同步通信
    ——也就是之前的代码
    2.线程池版本 Socket同步通信
    ——改进为线程池 初步验证也可以 但是没用异步的...
    3.线程池 Socket异步通信版本
    ——在研究 =。=!求指点