I am a WPF programmer and now is a beginner of UWP.
I need to write a new program to connect a remote machine now. And the machine will send data to the client at times.
I wanna that whenever the machine sends the data, the client will get it at once.
In WPF I can use the Asynchronous Client Socket
, whenever there is a data to the client, the ReceiveCallback
will get it at once as shown in this example.
However, in UWP it seems has not the Asynchronous Client Socket. I used the SteamSocket
to connect the remote machine successfully as below:
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;
}
});
Whereas, these codes can only read the data when you use the DataReader
, but not with an event to show it when received the data at once.
By using a loopback may solve it and I don't want the code being so ugly with the loopback.
I googled but found nothing useful about this.
I asked Microsoft engineer about this and he told me to use the SocketActivityTrigger
, I don't want to use it for it not only hard to use but also is a background worker. Even I exit the UWP program it will still connect to the remote machine and receive the data continuously.
Would you please tell me how to solve it?
To @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");
}
I used the StreamSocketListener
, but after I ran the program, it reports
'
{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()}
' What's wrong with this?
Thanks for @Nico Zhu helping me so much. Finally, I found a strange way to do it: using the socket of WPF in UWP
But it is strange that the socket of WPF has not the Asynchronous Client Socket in UWP, so that I can only do it like this:
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);
}
}
});