mvc上起udpserver 探索

 当前做一个数据采集温度湿度噪音的项目, 一如既往的按照互联网公司的做法,起一个c#mvc的项目, 概括来说c#的mvc 比java spring mvc 感觉简洁了很多,本人曾在几年前从winform 直接跳到了java sringmvc ,光配置都自己摸索了一阵子

当前公司用的asp.net 技术,于是乎又熟练了一下c#的mvc , 第一就是编辑器方面建一个项目很简单,配置就三几步,不像eclipse 的各种的配置啊.逻辑没写多少,配置先耽误一段时间.

回到主题, 采集数据采用udp的传输方式, 硬件那边据说是为了省电,于是乎我把udpserver 建到了mvc的项目中了,开始了一连串的调试

打开软件启动udpserver  需在Global.asax 内添加启动.我的理解是 mvc 没有 static void Main() 入口,在global中设置  RunUdpServer.Run(); //启动服务

最开始是从网页中启动的服务, 服务启动之后,在一段时间内没有请求,或者是10分钟, udpserver 出现无反应,链接断开,最开始判断是udpport 那个服务组件的版权问题, 现在看看不是应该人家组件版权问题,

于是乎,udpport 不行,找了另一个换上 ,本来觉得应该问题解决,后来又出现10分钟左右掉链子. 在那时,隔一段时间打开首页时没有连续打开的速度快,我感觉iis 有个慵懒机制,没有请求时估计服务都挂起了,要不为何第一次请求index 反应了一段时间.

到现在不能确定iis问题,因为毕竟websocket 也是tcp类似的东西在上边跑着没问题的..此时想到,mvc上启动udp server应该是行不通, mvc 提供的是http服务器, udp 也是个比http 甚至还低一层的协议,从应用分工的角度上看,应该单拿出来才对,用c# winform 实现udpserver ,mvc那块就提供网页展示查询就可以了.

开始从github上找udpserver , 关键词搜索也很重要,不带winform 出来的没有一个想要的

很多都是老一套接收数据时写个死循环,循环接收,难道不知道有那种事件接收的方式吗,(因为我看过netty 里边似乎就是监听端口,来了事件的方式通知的,这种方式消息很及时了)

 while (true)
                {
                    byte[] data = new byte[1024];
                    int length = 0;
                    try
                    {
                        length = udpServer.ReceiveFrom(data, ref Remote);//接受来自服务器的数据
                    }
............}

后来找到了

UdpClient-master

https://github.com/we-ciao/UdpClient

微软给我们提供了一个udpclient ,看看这个类,里边已经写好了接收事件, 我也发现网上有的代码中,也用了udpclient, 里边还是带了个while(true){}生搬硬套上的吧

这套源码经过测试,在本机上发本机是没问题的,有个问题就是在服务器上返回不到请求端,后来发现是源码启动了两个udpclient ,接收和发送用的不是同一个

这在公网上是有问题的

再后来发现上边的写法是正确的 while(true) 并不是死循循环,应该是socket.ReceiveFrom(buffer, ref endPointReceive); 跑到此函数之后,挂起了,在次函数下边加断点,除非有新数据,程序是运行不到的

第二, 事件接收是用于客户端接收事件的,套用到服务器端不好用

第三:udpclient 这个类不好用,在局域网内相互能测通,换到内网A 到B公网 ,B能收到A发的信息紧接着给A返回信息,A是接收不到的,这个问题一直没找到好的解决法子,网上千篇一律是在内网测试的例子,我的也通了换到公网就出问题

第四:彻底抛弃udpclient这个类 直接使用socket

 class Server
    {
        static void Main(string[] args)
        {
            var ipAddress = IPAddress.Parse("127.0.0.1"); // Your IP Address
            var port = 27001;

            using (var socket = new Socket(
                AddressFamily.InterNetwork,
                SocketType.Dgram,
                ProtocolType.Udp))
            {

                var endPoint = new IPEndPoint(ipAddress, port);
                socket.Bind(endPoint);
                var length = 0;
                var buffer = new byte[66000];
                List<byte> byteList = new List<byte>();
                EndPoint endPointReceive = new IPEndPoint(IPAddress.Any, 0);

                try
                {
                    int temp = 0;
                    while (true)
                    {
                        Console.WriteLine("Waiting...");
                        length = socket.ReceiveFrom(buffer, ref endPointReceive);

                        Console.WriteLine($"length: {length}");
                        byte[] a =  new byte[] { 0x30, 0x31 };

                        socket.SendTo(a, endPointReceive);

                        for (int i = 0; i < length; i++)
                        {
                            byteList.Add(buffer[i]);
                        }

                        temp++;
                        if (temp == 2) break;

                    }



                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    Console.ReadLine();
                }




                Console.WriteLine("list count: " + byteList.Count);

                // File writed
                FileStream fs = File.Create("uno.jpeg");
                fs.Write(byteList.ToArray());


                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
                Console.WriteLine("End");
                Console.ReadLine();


            }
        }
    }

上边代码中,客户端发送给服务器端,收到信息后,直接返回,是没有问题的.

经过几个版本的测试,问题总算是解决了.

资料: iis 的应用回收是不是导致udpserver 被关掉,在下边可以做个参考

   最近在做一个项目,需要在程序中定时不断的执行某些操作,结果发现每天7,8点过后到第二天9点,定时程序经常都没有在执行,后来才知道由于IIS的应用池回收导致Application停止,而这段时间又没有人再次访问网站,结果在Application_Start中的定时执行程序代码就没有再执行,在网上搜索一番,找到了解决办法,现和大家一起分享交流,原理就是在应用程序结束时发出一个Web请求访问网站,启动Application_Start。

    void Application_End(object sender, EventArgs e)
    {
        //  在应用程序关闭时运行的代码
       
        //解决应用池回收问题
        System.Threading.Thread.Sleep(5000);
        string strUrl = "网站地址";

        System.Net.HttpWebRequest _HttpWebRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strUrl);
        System.Net.HttpWebResponse _HttpWebResponse = (System.Net.HttpWebResponse)_HttpWebRequest.GetResponse();
        System.IO.Stream _Stream = _HttpWebResponse.GetResponseStream();//得到回写的字节流
    }
原文地址:https://www.cnblogs.com/zuochanzi/p/13518241.html