如果客户端设置监听6000端口的话,服务器端应该发送到客户端6000端口,服务器端收到的客户端请求的端口号之所以不同是因为初始化socket的时候没有进行端口绑定,系统会随机分配一个端口号给程序。

解决方案 »

  1.   


    正解    public class UDPSocketService
        {        //private  static Socket          ServerSocketSender;
            private static int ServerUDPPortSend = 6790; // 
            private static Socket ServerSocketReceiver;
            private static AsyncCallback UDPReceiveCallback;             //udp回调函数 
            private static byte[] dataBuffers;                    //udp字节缓存  
            private static EndPoint ServerEndPoint;
            private static IPAddress svrIPAddress;        public static IPAddress ServerIPAddress
            {
                get { return UDPSocketService.svrIPAddress; }
                set { UDPSocketService.svrIPAddress = value; }
            }
            private static int svrUDPPortReceive = 9051; //          internal static int ServerUDPPortReceive
            {
                get { return UDPSocketService.svrUDPPortReceive; }
                set { UDPSocketService.svrUDPPortReceive = value; }
            }
            ///// <summary>
            ///// 取安装本软件的服务器ip
            ///// </summary>
            ///// <returns></returns>
            //public static IPAddress GetLocalIP()
            //{
            //    IPHostEntry iphostentry = Dns.GetHostByName(Dns.GetHostName());
            //    IPAddress HostIP = null;
            //    if (iphostentry.AddressList.Length > 0)
            //    { HostIP = iphostentry.AddressList[0]; }
            //    return HostIP;
            //}
            public static void UDPDataSend(byte[] data)
            {
                try
                {                Socket ServerSocketSender = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    IPEndPoint iepBroadcast = new IPEndPoint(IPAddress.Broadcast, ServerUDPPortSend);//255.255.255.255                ServerSocketSender.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
                    ServerSocketSender.SendTo(data, iepBroadcast);  //An operation was attempted on something that is not a socket
                    ServerSocketSender.Close();
                }
                catch (Exception se)
                {
                    BizLogic.LogWriter.AddSystemException(se);
                }        }
            public static void UDPDataSendTo(byte[] data, string IPAdd)
            {
                try
                {
                    if (string.IsNullOrEmpty (IPAdd) == true  || IPAdd == "N/A")
                    { return; }
                    Socket ServerSocketSender = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    IPEndPoint iepBroadcast = new IPEndPoint(IPAddress.Parse(IPAdd), ServerUDPPortSend);//255.255.255.255                ServerSocketSender.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
                    ServerSocketSender.SendTo(data, iepBroadcast);
                    ServerSocketSender.Close();
                }
                catch (Exception se)
                {
                    BizLogic.LogWriter.AddSystemException(se);
                }        }        /// <summary>
            /// 后台监听接收
            /// </summary>
            public static void UDPOnListen()
            {
                try
                {
                     
                        dataBuffers = new byte[2048];
                        //svrIPAddress = GetLocalIP();
                        //System.Windows.Forms.MessageBox.Show(svrIPAddress.ToString(), svrUDPPortReceive.ToString());                    ServerEndPoint = new IPEndPoint(svrIPAddress, svrUDPPortReceive);                    UDPReceiveCallback = new AsyncCallback(UDPDataReceived);                    ServerSocketReceiver = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                        ServerSocketReceiver.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
                       
                        //ServerSocketReceiver.Bind(ServerEndPoint);//不允许运行第二个该下载工具,在这会报异常
                        try
                        {
                            ServerSocketReceiver.Bind(ServerEndPoint);//不允许运行第二个该下载工具,在这会报异常
                        }
                        catch (System.Net.Sockets.SocketException ex)
                        {
                            if (ex.SocketErrorCode == System.Net.Sockets.SocketError.AddressAlreadyInUse)
                            {
                                System.Windows.Forms.MessageBox.Show("监听端口已被其他程序占用,不能正确获得在线播放器信息,请退出程序?",
                              "端口占用错误", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                               
                            }
                            throw ex;                    }                    ServerSocketReceiver.ReceiveTimeout = 5;
                        ServerSocketReceiver.ReceiveBufferSize = 2048;                    ServerSocketReceiver.BeginReceiveFrom(dataBuffers, 0, dataBuffers.Length, SocketFlags.None,
                            ref   ServerEndPoint, UDPReceiveCallback, ServerSocketReceiver);
                                 }
                catch (Exception ex)
                {
                    BizLogic.LogWriter.AddSystemException(ex);
                }        }
            /// <summary>
            /// UDP回调
            /// </summary>
            /// <param name="ar"></param>
            private static void UDPDataReceived(IAsyncResult ar)
            {
                try
                {
                    Socket udpSocket = ar.AsyncState as Socket;
                    //070128  退出时异常:由于线程退出或应用程序请求,已放弃 I/O 操作
                    int bytesRecved = udpSocket.EndReceiveFrom(ar, ref   (EndPoint)ServerEndPoint);
                    //当收到数据后,数据已在dataBuffers,把dataBuffers转换成可识别的结构体,依据命令类型Type                //接收到的package是来自哪个ipaddress,把dataBuffers,ipaddress传过去,在第一次刷新时显示
                    BizLogic.DataProcessor.DataFilter(dataBuffers);
                    System.Threading.Thread.Sleep(5);
                    ServerSocketReceiver.BeginReceiveFrom(dataBuffers, 0, dataBuffers.Length, SocketFlags.None,
                        ref  ServerEndPoint, UDPReceiveCallback, ServerSocketReceiver);
                }
                catch (Exception ex)
                {
                    BizLogic.LogWriter.AddSystemException(ex);
                }
            }
            public static bool IsUDPConnected()
            {
                if (ServerSocketReceiver.Connected == true)//判断UDP接受的状态
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            public static void Close()
            {
                if (ServerSocketReceiver == null)
                    return;
                if (ServerSocketReceiver.Connected == true)
                { ServerSocketReceiver.Close(); }
            }
         }
      

  2.   

    确实应该是6000端口,因为你使用的是UDP协议,这个协议是不会保持连接的,是不可靠连接。
    如果是改用TCP协议的话,就可以使用原来的连接,而不需要新建一个连接。
      

  3.   

    通用的,客户端和服务端的监听端口互换一下就可以了,用时直接UDPSocketService.去调启动            ////启动UDP套接字监听----20080408            UDPSocketService.ServerIPAddress = startip;
                UDPSocketService.ServerUDPPortReceive = startport;
                UDPSocketService.UDPOnListen(); 关闭 
     UDPSocketService.Close();点对点发送
    UDPSocketService.UDPDataSendTo(你的数据,目的地)收包要另写一个静态方法
    //  BizLogic.DataProcessor.DataFilter(dataBuffers);
      

  4.   

    不太喜欢全是static的类型,比较难做单元测试。