Как я могу непрерывно получать данные с сервера через streamsocket? - PullRequest
0 голосов
/ 03 ноября 2018

Я программист WPF, а сейчас начинающий UWP.

Мне нужно написать новую программу для подключения удаленного компьютера сейчас. И машина будет отправлять данные клиенту время от времени.

Я хочу, чтобы всякий раз, когда машина отправляла данные, клиент получал их сразу.

В WPF я могу использовать Asynchronous Client Socket, когда у клиента есть данные, ReceiveCallback сразу получит , как показано в этом примере .

Однако в UWP, похоже, нет асинхронного клиентского сокета. Я использовал SteamSocket для успешного подключения к удаленной машине, как показано ниже:

 Task.Run(async()=>{
                try
                {
                    StreamSocket SS = new StreamSocket();
                    await SS.ConnectAsync(new Windows.Networking.HostName("192.168.200.111"), "23");

                    DataWriter writer = new DataWriter(SS.OutputStream);
                    string content = "ST";
                    byte[] data = Encoding.UTF8.GetBytes(content);
                    writer.WriteBytes(data); 
                    await writer.StoreAsync();
                    writer.DetachStream();
                    writer.Dispose();

                    DataReader reader = new DataReader(SS.InputStream);
                    reader.InputStreamOptions = InputStreamOptions.Partial;
                    await reader.LoadAsync(1024);
                    string response = reader.ReadString(reader.UnconsumedBufferLength);
                    Debug.WriteLine(response);                       
                }
                catch(Exception ex)
                {
                    throw ex;
                }
            });

Принимая во внимание, что эти коды могут считывать данные только при использовании DataReader, но не с событием, которое показывает их при получении данных сразу.

Использование петли может решить эту проблему, и я не хочу, чтобы код был таким уродливым с петлей.

Я погуглил, но ничего полезного в этом не нашел.

Я спросил об этом инженера Microsoft, и он сказал мне использовать SocketActivityTrigger, я не хочу использовать его, поскольку он не только сложен в использовании, но и является фоновым работником. Даже если я выйду из программы UWP, она все равно будет подключаться к удаленной машине и непрерывно получать данные.

Не могли бы вы сказать, как ее решить?


Для @Nico Zhu:

 private void Button_Click(object sender, RoutedEventArgs e)
        {
            Task.Run(async()=>{
                try
                {                    
                    StreamSocketListener SSL = new StreamSocketListener();
                    SSL.ConnectionReceived += SSL_ConnectionReceived;
                    await SSL.BindEndpointAsync(new Windows.Networking.HostName("192.168.200.111"), "23");

                }
                catch(Exception ex)
                {
                    throw ex;
                }
            });
        }

        private void SSL_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
        {
            Debug.WriteLine("123");
        }

Я использовал StreamSocketListener, но после запуска программы она сообщает «

{System.Runtime.InteropServices.COMException (0x80072741): The requested address is not valid in its context

   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at App2.MainPage.<<Button_Click>b__2_0>d.MoveNext()}

Что с этим не так?

1 Ответ

0 голосов
/ 07 ноября 2018

Спасибо, что @Nico Zhu мне так сильно помог. Наконец, я нашел странный способ сделать это: использовать сокет WPF в UWP

Но странно, что сокет WPF не имеет асинхронного клиентского сокета в UWP, поэтому я могу сделать это только так:

 await Task.Factory.StartNew(async () =>
            {
                IPEndPoint ip = new IPEndPoint(IPAddress.Parse("192.168.200.111"), 23);
                Socket S = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                S.Connect(ip);
                S.Send(Encoding.UTF8.GetBytes("SS" + Environment.NewLine));
                while (true)
                {
                    byte[] buffer = new byte[1024];
                    if (S.Available != 0)
                    {
                        S.Receive(buffer);
                        Debug.WriteLine(Encoding.UTF8.GetString(buffer));
                        Debug.WriteLine("");
                        await Task.Delay(100);
                    }
                }
            });
...