设备进入深度睡眠状态后,套接字关闭-Android Xamarin

时间:2020-07-27 07:15:10

标签: android sockets xamarin

我创建了一个简单的TCP服务器,用于将通知发送到android应用(xamarin)。

当应用程序在前台运行时,它可以正常工作,但是当我在1-3分钟内休眠设备(锁定设备)后,我收到一条错误消息-服务器上的“远程主机强行关闭了现有连接”我失去了联系。

我已经在android项目中创建了一个服务来处理连接。

测试服务器:

namespace AsyncServer
{
    class Program
    {
        private static byte[] _buffer = new byte[2048];
        private static List<connectedUser> Users = new List<connectedUser>();
        private static Socket _serverSocket = new Socket
            (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private static int port = 25565;


        static void Main(string[] args)
        {
            SetupServer();
            while (true)
            {

                //Console.WriteLine("pick user name");
                string userText = "User";// Console.ReadLine();
                Console.WriteLine("Enter");
                string re = Console.ReadLine();

                string json = JsonConvert.SerializeObject(new NotificationOrderModel() { User = "Server", Name = re});
                byte[] buffer = Encoding.UTF8.GetBytes(json);

                if (Users != null)
                {
                    foreach (connectedUser user in Users.ToList())
                        if (user.Name == userText)
                            Send(user, buffer);
                }


            }

        }

        private static void Send(connectedUser user , byte [] buff) 
        {
            try
            {
                user._clientSocket.BeginSend(buff, 0, buff.Length, SocketFlags.None, new AsyncCallback(SendCallback), user._clientSocket);
            }
            catch (Exception)
            {
                Users.Remove(user);    
            }
        } 

        private static void SetupServer()
        {
            Console.WriteLine("setting server");
            _serverSocket.Bind(new IPEndPoint(IPAddress.Any, port));
            _serverSocket.Listen(5);
            _serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
        }

        private static void AcceptCallback(IAsyncResult AR)
        {       
            Socket socket = _serverSocket.EndAccept(AR);
            socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
            _serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket);
        }
        private static void ReceiveCallback(IAsyncResult AR)
        {
            try
            {
                Socket socket = (Socket)AR.AsyncState;
                int received = socket.EndReceive(AR);
                if (received > 0)
                {
                    byte[] dataBuf = new byte[received];
                    Array.Copy(_buffer, dataBuf, received);
                    string data = Encoding.UTF8.GetString(dataBuf);
                    var tmp = JsonConvert.DeserializeObject<NotificationOrderModel>(data);

                    if (Users != null)
                    {
                        bool flag = false;
                        foreach (connectedUser user in Users.ToList())
                            if (user._clientSocket == socket)
                                flag = true;

                        if (flag)
                            ;
                        else
                        {
                            Users.Add(new connectedUser() { Name = tmp.User, _clientSocket = socket });
                            Console.WriteLine("connected - " + tmp.User); // to be removed
                        }
                    }





                    if (tmp.isPing)
                    {
                        string json = JsonConvert.SerializeObject(new NotificationOrderModel() { User = "Server", isPing = true });
                        if (Users != null)
                        {
                            foreach (connectedUser user in Users.ToList())
                                if (user.Name == tmp.User)
                                    Send(user, dataBuf);
                        }
                    }
                    

                }
                socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
            }
            catch (SocketException ex) 
            {
                //when user disconnects - closes the application
            }
        }

        private static void SendCallback(IAsyncResult AR)
        {
            Socket socket = (Socket)AR.AsyncState;
            socket.EndSend(AR);
        }


    }

    class connectedUser 
    {
        public string Name;
        public Socket _clientSocket;
    }


    public class NotificationOrderModel //:  OrderModel, ICloneable
    {
        public string Name;
        public decimal Qty;
        public string ServingPlace;
        public string User;
        public bool Seen = false;
        public bool isPing = false;

        public NotificationOrderModel()
        {

        }
    }


}

Android中的套接字服务:

 [Service]
    [assembly: Dependency(typeof(SocketService))]
    public class SocketService : Service
    {
        public override IBinder OnBind(Intent intent)
        {
            return null;
        }

        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            Ping();
            return StartCommandResult.Sticky;
        }

        public override void OnDestroy()
        {
            //if (_cts != null)
            //{
            //  _cts.Token.ThrowIfCancellationRequested();

            //  _cts.Cancel();
            //}
            base.OnDestroy();
        }


        public static ObservableCollection<NotificationOrderModel> OrderList = new ObservableCollection<NotificationOrderModel>();
        private static Socket _serverSocket = new Socket
           (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        private static byte[] _buffer = new byte[2048];
        private static string IP = App.Settings.ServerIP; 
        private const int port = 25565;
        private static IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(IP), port);
        public static bool Connected = false;



        public static async Task<bool> Start()
        {

            if (!Connected)
            {
                //_serverSocket.ReceiveTimeout
                _serverSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), _serverSocket);

                if (_serverSocket.Connected == true)
                    Connected = true;
            }
            try
            {
                if (Connected == true)
                {
                    // Console.ReadLine();
                    string json = JsonConvert.SerializeObject(new NotificationOrderModel() { User = App.DataProvider.User.Username, isPing = true });
                    byte[] data = Encoding.UTF8.GetBytes(json); //"test"
                    _serverSocket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), _serverSocket);
                    _serverSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), _serverSocket);
                }
            }
            catch (Exception)
            {
                Connected = false;
            }


            return false;
        }
        //initiate 
        //ping
        private static void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;
                client.EndConnect(ar);
                //Console.Clear();
                Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString());
                Connected = true;
            }
            catch (Exception e)
            {
                Thread.Sleep(200);
                _serverSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), _serverSocket);
                //Console.Clear();
                Console.WriteLine("Attempting to connect");
            }
        }

        private static void ReceiveCallback(IAsyncResult AR)
        {
            try
            {
                Socket socket = (Socket)AR.AsyncState;
                int received = socket.EndReceive(AR);
                if (received > 0)
                {
                    byte[] dataBuf = new byte[received];
                    Array.Copy(_buffer, dataBuf, received);
                    string data = Encoding.UTF8.GetString(dataBuf);
                    var tmp = JsonConvert.DeserializeObject<NotificationOrderModel>(data);
                    if (!tmp.isPing)
                    {
                        OrderList.Add(tmp);
                        // DependencyService.Get<INotification>().CreateNotification("title", "text");                      
                    }
                }
                socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
            }
            catch (SocketException ex)
            {
                //throw;
            }
        }

        private static void SendCallback(IAsyncResult AR)
        {
            Socket socket = (Socket)AR.AsyncState;
            socket.EndSend(AR);
        }



        private static async Task<bool> Initialized()
        {
            _serverSocket.ReceiveTimeout = -1;
            _serverSocket.SendTimeout = -1;
            _serverSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), _serverSocket);

            try
            {
                Thread.Sleep(1000);
                _serverSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), _serverSocket);
                string json = JsonConvert.SerializeObject(new NotificationOrderModel() { User = App.DataProvider.User.Username, isPing = true });
                byte[] data = Encoding.UTF8.GetBytes(json);
                _serverSocket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), _serverSocket);
            }
            catch (SocketException ex)
            {
                Connected = false;
                // _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ;
            }
            return true;
        }

        public static async Task<bool> Ping()
        {
            if (Connected != true)
                return await Initialized();
            else
            {
                try
                {
                    string json = JsonConvert.SerializeObject(new NotificationOrderModel() { User = App.DataProvider.User.Username, isPing = true });
                    byte[] data = Encoding.UTF8.GetBytes(json);
                    _serverSocket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), _serverSocket);

                }
                catch (Exception)
                {
                    Connected = false;
                    return false;
                }

            }
            return false;
        }

    }

我以此启动服务:

 var intent = new Intent(this, typeof(SocketService));
                StartService(intent);

0 个答案:

没有答案