大家好,很久没有在CSDN上提问了。目前遇到了棘手的问题,请大家帮忙。
搞了四年B/S结构,最近公司有一个很紧的项目,是C/S结构的程序(具体需求我下面说),我不得不放下手中的项目,帮忙研究这个项目,公司居然没有人搞过多线程的Socket,不得已我就担负起了攻坚的责任,时间很紧,希望大家帮忙,原始的需求框架很简单,我大概描述下,希望有对这个熟悉的朋友能联系我,我感觉这个东西熟悉的人半个小时就弄出来了,不胜感谢。服务端:(其实这个项目在技术角度没有所谓的服务端和客户端,具体请听我说完)
在本地开个端口监听,因为是窗体,所以要另开线程侦听,同时在有客户端请求连接时,为每个客户端新建线程,客户端在请求连接的时候,直接就向服务端发送消息,在服务端接收后断开这个TCP连接,这是个重点,要实现连接为瞬时。客户端:
其实客户端也会有个端口做侦听,这就是为什么我说技术角度不分服务端和客户端的原因,服务端每过一段时间,会执行一段函数判断一些设备的状态,如果出现异常,那么循环向该网段下比如192.168.1.101-192.168.1.254这些客户端发送消息,每个向客户端的连接请求也新建一个线程,同时这个连接也是瞬时的,发送完消息就断开。大概需求就是这样,希望懂的人给于帮助,实在没玩过C/S,找了些代码也没什么进展,有热心的朋友请加Q:56326931

解决方案 »

  1.   

    lz目前的这个C/S构架, 对于做过通讯方面的C/S控制在平常不过了
    个人觉得最重要的也是中断的算法和Socket通讯的稳定了
      

  2.   

    顶一下,关注
    c/s的这套东西还是有点搞的特别是和通信相关的
    建议LZ 自己写socket的不要用.net封装的那套,.net封装的那个效率很低,而且开销很大,容易出问题
      

  3.   

    你想快点就看我的博客
    LumiSoft.Net
    用这个都解决的
    白天我不能QQ
    [email protected]
    另外你得帮我解决个问题
      

  4.   

    有TCP和UDP两种连接方式,如果是内网使用的就简单很多了,随便搜索都能找到你需要的。
    搜索关键字:c# socket
    这个真的是到处都是,只要原理明白了,很简单的。
    如果不明白原理,C#这方面的资料我不很清楚,C++的有个视频教程,孙鑫的,第14和15讲专门讲这个的,可以看一下,很简单。
    如果是外网使用的,稍微麻烦一点,主要就是nat穿透问题,把4种nat类型弄明白就可以了,可以使用stun穿透。
      

  5.   

    可扩展多线程异步Socket服务器框架EMTASS 2.0
      

  6.   

    多谢大家的回复,主要是从来没有接触过C/S,一上来就是多线程,可能是B/S的思路存在局限性。我再研究下,希望懂的人多给意见。
      

  7.   

    1:SOCKET肯定是需要多线程的,因为 服务端监听->接收->处理->回发 这种模式很类似事件处理方式。
    2:system.net 已有微软此功能套件。
    3: 如果可以,其实大可以用Remoting Service 或 WPF, 因为所有通讯基本要求它都帮你搞定了。
      

  8.   

    我只用过单独的 socket 通讯  开端口 很无聊的
      

  9.   

    客户端:实例化客户端TcpClient
    TcpClient  client = new TcpClient(192.168.1.200, 51888); 
    然后启动侦听线程。侦听线程一般是While 循环过程。
    一旦侦听失败。捕获异常,即中断与服务端连接。服务端:TcpListener
    创建一个线程监听客户端连接请求
      

  10.   

    刚好手头上有一个,给你参考下吧。
    运行还算问题,本地测试过100个终端连接,支持心跳检测。
     /// <summary>
            /// 启动帧听服务
            /// </summary>
            /// <returns></returns>
            public bool StartServer()
            {
                if (serverThread == null)
                {
                    serverThread = new Thread(new ThreadStart(Server));
                    serverThread.Start();
                }
                else
                {
                    IsListener = true;
                }
                return true;
            }
            /// <summary>
            /// 停止帧听服务
            /// </summary>
            /// <returns></returns>
            public bool StopServer()
            {
                if (serverThread != null)
                {
                    IsListener = false;
                    //必须等待下面的接收连接THREAD方法运行完毕后才能关闭STOP
                    //否则会出现错误 一个封锁操作被对WSACancelBlockingCall的调用阻塞
                    while (isRun == true)
                    {
                        Thread.Sleep(10);
                    }
                    localServer.Stop();
                    //并关闭所有已经启动的线程
                    if (current485List != null && current485List.Count > 0)
                    {
                        foreach (DealBuseness serv in current485List)
                        {
                            serv.Stop();
                        }
                    }
                    serverThread = null;
                }
                return true;
            } /// <summary>
            /// 帧听服务
            /// </summary>
            private void Server()
            {
                localServer = new TcpListener((Dns.GetHostAddresses(Dns.GetHostName()))[0], port);
                localServer.Start();
                while (isListener)
                {
                    System.Threading.Thread.Sleep(100);
                    isRun = true;
                    if (localServer.Pending())
                    {
                        Socket currentSocket = localServer.AcceptSocket();
                        IPEndPoint currPoint = (IPEndPoint)currentSocket.RemoteEndPoint;
                        Server485 current485 = new Server485(currPoint.Address.ToString(), currPoint.Port, currentSocket);
                        DealBuseness currDeal = new DealBuseness(ref current485, currentForm, delegtCard, delegt485);
                        currDeal.Start();
                        if (current485List == null)
                        {
                            current485List = new List<DealBuseness>();
                        }
                        current485List.Add(currDeal);
                        if (currentForm != null && delegt485 != null)
                        {
                            currentForm.Invoke(delegt485, currPoint.Address.ToString(), true);
                        }
                    }
                }
                isRun = false;
            }帧听后,对每一个SOCKET建立了三个线程,发送、接受、处理。主要是自己的程序要求,实现异步双通道!
    总体来说,。NET的SOCKET还是比较好操作的,至于那些说要自己封装的,个人认为如果不是对底层非常熟悉,
    还是用自带的好。
      

  11.   

    我一直参考这篇文章来写异步socket的,精读细读多调试
    http://www.cnblogs.com/idior/articles/147648.html
      

  12.   

    这个比较好理解,也比较好做。对于服务端:只需要一直进行监听,当监听到有连接请求的时候,调用函数生成一个新的线程,用与处理你的通讯(接收消息),接受完消息以后,该连接断开,然后将强制结束该线程,以便节约资源。
    对于客户端,可以采取同样的手段进行。我以前做过相似的,如果需要可以直接联系。顺便说一点:一般的话,采取socket进行通讯,都要进行多线程的,要不然每次只能单线联系,没有更多的人通讯,感觉向特务。呵呵
      

  13.   

    http://topic.csdn.net/u/20080623/08/4bbd2475-45f1-42e3-a613-16b094759ade.html
      

  14.   

    CSDN上的人真热情,埋头研究了两天,一筹莫展也一直没有来CSDN提问,因为不敢报希望,以前提问很少人回答,就是回答也是混分。所以一直也只是在CSDN上回答问题而已,昨天半夜实在没有办法,就发了这篇帖子,今天就有很多朋友加我给于思路,我真的没有想到,这次的困难不管最后如何,我也认识了很多很好的朋友,真的谢谢大家。