C# Socket udp 本地通讯一直正常 发布到公网后 就只有第一次数据收发正常

C# Socket udp 本地通信一直正常 发布到公网后 就只有第一次数据收发正常
具体情况是这样。

我在本机 开服务端 和客户端 客户端无论何时发送消息 服务端在回给客户端确认消息 都是正常的。

但是我把服务端 发布在公网,我 第一次 发送消息给客户端 服务端 立马 能回消息给客户端,但是 假设我这个时候客户端什么都不做,等过 个 5 6 分钟在去发送消息给服务端,服务端 能接收到消息,可是服务端回给客户端的确认消息 客户端就接收不到了。
客户端程序每4分钟 会发个 心跳包给服务端。

如果不停发送消息 服务端回的消息还是能接到的,就是不能停顿,停个几分钟感觉 socket 就收不到消息.



这个问题 困扰我N久了 实在找不到原因 才发帖求助 ,求做过类似功能的朋友 帮忙解答下。 
下面上代码.


客户端
C# code


 try
            {
                byte[] data = new byte[1024];
                string msg;

                //构建UDP服务器

                // Console.WriteLine("This is a Client, host name is {0}", Dns.GetHostName());

                //设置服务IP,设置UDP端口号


                //定义网络类型,数据连接类型和网络协议UDP
                

                string welcome = "L" + UserHelper.loginUser.id.ToString();
                data = Encoding.UTF8.GetBytes(welcome);
                sokClient.SendTo(data, data.Length, SocketFlags.None, ipep);
                byte[] arrMsg2 = System.Text.Encoding.UTF8.GetBytes("H"+UserHelper.loginUser.id.ToString());
                sokClient.SendTo(arrMsg2, arrMsg2.Length, SocketFlags.None,ipep);

                IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
                EndPoint Remote = (EndPoint)sender;
                data = new byte[1024];
                //对于不存在的IP地址,加入此行代码后,可以在指定时间内解除阻塞模式限制
                //server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 100);
                int recv = sokClient.ReceiveFrom(data, ref Remote);
                Console.WriteLine(" from {0}: ", Remote.ToString());
                Console.WriteLine(Encoding.UTF8.GetString(data, 0, recv));
                

                while (true)
                {




                    //server.SendTo(Encoding.UTF8.GetBytes("ok"), Remote);
                    data = new byte[1024];
                    recv = sokClient.ReceiveFrom(data, ref Remote);
                    msg = Encoding.UTF8.GetString(data, 0, recv);

                    if (msg.Length > 0)
                    {
                        string headCommand = msg.Substring(0, 1);

                        switch (headCommand)
                        {
                            case "N":
                                string content = msg.Substring(1);
                                //MsgNewsForm mnf = new MsgNewsForm(content);
                              //  MsgPresentationManage.GetInstance().AddMsgNewsForm(mnf);

                                MessageBox.Show(msg);

                                break;
                            case "M":
                                string sendUserId = msg.Substring(1);
                                OAUsers user = userBLL.GetModel(int.Parse(sendUserId));
                                UserHelper.SendUserName = user.userName;
                                timerSend.Enabled = true;
                                timerSend.Start();
                                notifyIcon1.Icon = PPSoft.Properties.Resources._1;
                                break;
                            case "H":
                                string heartUserId = msg.Substring(1);
                                Console.WriteLine(heartUserId + "发来的心跳包");
                                break;
                            default: break;
                        }

                    }

                    Console.WriteLine(msg);
                }
            }
            catch (Exception ex)
            {
                
               
            }






服务端:
C# code

 int recv;
            byte[] data = new byte[1024];

            //构建UDP服务器

            //得到本机IP,设置UDP端口号         
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 8001);
            Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            //绑定网络地址
            newsock.Bind(ipep);

           // Console.WriteLine("This is a Server, host name is {0}", Dns.GetHostName());

            //等待客户机连接
            Console.WriteLine("等待客户端连接...");

            //得到客户机IP
            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
            EndPoint Remote = (EndPoint)(sender);

             while (true)
            {
                data = new byte[1024];
                //发送接受信息
                recv = newsock.ReceiveFrom(data, ref Remote);
                Console.WriteLine(Encoding.UTF8.GetString(data, 0, recv));


                string msg = Encoding.UTF8.GetString(data, 0, recv);



                try
                {
                    if (msg.Length > 0)
                    {
                      

                        string headCommand = msg.Substring(0, 1);

                        switch (headCommand)
                        {
                            case "A":
                                //心跳包
                                
                                
                                Console.WriteLine("心跳包:" + msg);
                               // string heartUserId = msg.Substring(1);
                               // byte[] heartNews = Encoding.UTF8.GetBytes("H" + heartUserId);

                                //newsock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);

                                //foreach (string uId in userIps.Keys)
                                //{
                                //    newsock.SendTo(heartNews, heartNews.Length, SocketFlags.None, userIps[uId]);
                               // }
                                
                                break;
                            case "H":
                                //心跳包


                                
                                string heartUserId = msg.Substring(1);
                                byte[] heartNews = Encoding.UTF8.GetBytes("H" + heartUserId);

                                newsock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);

                                foreach (string uId in userIps.Keys)
                                {
                                    newsock.SendTo(heartNews, heartNews.Length, SocketFlags.None, userIps[uId]);
                                }

                                break;

                            case "L":
                                Console.WriteLine("客户端请求-来自: {0}: ", Remote.ToString());
                                Console.WriteLine(msg);
                                string userId = msg.Substring(1);

                                if (!userIps.ContainsKey(userId))
                                {

                                    userIps.Add(userId, Remote);
                                }
                                else
                                {
                                    userIps[userId] = Remote;
                                }

                                break;
                             //发布新闻
                            case "N":
                                string content = msg.Substring(1);

                                byte[] returnNews = Encoding.UTF8.GetBytes("N"+content);
                                newsock.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.Broadcast, 1); 
                                

                                foreach (string uId in userIps.Keys)
                                {
                                    newsock.SendTo(returnNews, returnNews.Length, SocketFlags.None, userIps[uId]);
                                }

                                
                                break;
                            case "M":
                                Console.WriteLine(msg);
                                int index = msg.IndexOf("#");

                                string sendUserId = msg.Substring(1, index - 1);
                                string sendUserIds = msg.Substring(index + 1);

                                byte[] returnMsg = Encoding.UTF8.GetBytes("M" + sendUserId);



                                newsock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);

                                foreach (string sendId in sendUserIds.Split(','))
                                {
                                    if (sendId != "")
                                    {
                                        if (userIps.ContainsKey(sendId))
                                        {

                                            newsock.SendTo(returnMsg, returnMsg.Length, SocketFlags.None, userIps[sendId]);
                                        }
                                    }
                                }

                                break;
                            default: break;

                        }

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