Как я могу получать данные с сервера через streamsocket непрерывно?
Я программист 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 ответ
Спасибо за то, что @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);
}
}
});