C# UWP数据包多播

C# UWP数据包多播,c#,xaml,uwp,datagram,uwp-xaml,C#,Xaml,Uwp,Datagram,Uwp Xaml,我设法制作了一个简单的应用程序,从多播组发送和接收数据。如果我打开应用程序的两个实例(两个不同的.sln文件,代码相同),我就可以发送和接收数据。问题是5秒钟后,如果我从Client001发送消息,只有Client001会收到消息。但是,如果我在5秒内从Client002(应用程序的第二个实例)发送消息,那么他们两个都会收到消息。 我有一个UdpClient的例子,它工作得很好,但它不再适用于UWP。 总之,我该如何实现,无论何时(不是在5秒内)一些客户端发送消息,所有其他客户端都会收到 这是M

我设法制作了一个简单的应用程序,从多播组发送和接收数据。如果我打开应用程序的两个实例(两个不同的.sln文件,代码相同),我就可以发送和接收数据。问题是5秒钟后,如果我从Client001发送消息,只有Client001会收到消息。但是,如果我在5秒内从Client002(应用程序的第二个实例)发送消息,那么他们两个都会收到消息。 我有一个UdpClient的例子,它工作得很好,但它不再适用于UWP。 总之,我该如何实现,无论何时(不是在5秒内)一些客户端发送消息,所有其他客户端都会收到

这是MainPage.xaml.cs的代码

namespace Client001
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private DatagramSocket listenerSocket = null;
        public string remoteAddress = "224.3.0.5";
        HostName remoteHostname;
        public string serviceName = "22113";
        IOutputStream outputStream;
        DataWriter writer;

        public MainPage()
        {
            this.InitializeComponent();
            SetupMulticastScenarioUI();

            remoteHostname = new HostName(RemoteAddress.Text);
        }

        private void CloseListenerSocket()
        {
            if (listenerSocket != null)
            {
                // DatagramSocket.Close() is exposed through the Dispose() method in C#.
                // The call below explicitly closes the socket, freeing the UDP port that it is currently bound to.
                listenerSocket.Dispose();
                listenerSocket = null;
            }
        }

        // Sets up the UI to display the multicast scenario options.
        private void SetupMulticastScenarioUI()
        {
            RemoteAddress.Text = remoteAddress;
            ServiceName.Text = serviceName;
            StartListener.Content = "Start listener and join multicast group";
            SendMessageButton.IsEnabled = false;
            CloseListenerButton.IsEnabled = false;
            SendOutput.Text = "";
        }

        private async void StartListener_Click(object sender, RoutedEventArgs e)
        {
            listenerSocket = new DatagramSocket();

            listenerSocket.Control.MulticastOnly = true;
            await listenerSocket.BindServiceNameAsync(ServiceName.Text);

            // Join the multicast group to start receiving datagrams being sent to that group.
            listenerSocket.JoinMulticastGroup(remoteHostname);

            listenerSocket.MessageReceived += MessageReceived;
            SendOutput.Text = "Listening on port " + listenerSocket.Information.LocalPort + " and joined to multicast group";

            // Enable scenario steps that require us to have an active listening socket.
            SendMessageButton.IsEnabled = true;
            CloseListenerButton.IsEnabled = true;

            outputStream = await listenerSocket.GetOutputStreamAsync(remoteHostname, ServiceName.Text);
            writer = new DataWriter(outputStream);
            writer.WriteString("Handshake1");
            await writer.StoreAsync();
        }

        private async void SendMessage_Click(object sender, RoutedEventArgs e)
        {
            writer.WriteString(Message.Text);
            await writer.StoreAsync();
        }

        private void CloseListener_Click(object sender, RoutedEventArgs e)
        {
            CloseListenerSocket();

            // Disable scenario steps that require us to have an active listening socket.
            SendMessageButton.IsEnabled = false;
            CloseListenerButton.IsEnabled = false;
            SendOutput.Text = "";

            SendOutput.Text = "Listener closed";
        }

        async void MessageReceived(DatagramSocket socket, DatagramSocketMessageReceivedEventArgs eventArguments)
        {
            // Interpret the incoming datagram's entire contents as a string.
            uint stringLength = eventArguments.GetDataReader().UnconsumedBufferLength;
            string receivedMessage = eventArguments.GetDataReader().ReadString(stringLength);

            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                SendOutput.Text = "Received data from remote peer (Remote Address: " +
                    eventArguments.RemoteAddress.CanonicalName + ", Remote Port: " +
                    eventArguments.RemotePort + "): \"" + receivedMessage + "\"";
            });
        }
    }
}
名称空间Client001
{
/// 
///可以单独使用或在框架内导航到的空页。
/// 
公共密封部分类主页面:第页
{
私有DatagramSocket listenerSocket=null;
公共字符串remoteAddress=“224.3.0.5”;
主机名远程主机名;
公共字符串serviceName=“22113”;
IOutputStream输出流;
数据作者;
公共主页()
{
this.InitializeComponent();
SetupMulticastScenarioUI();
remoteHostname=新主机名(RemoteAddress.Text);
}
私有void CloseListenerSocket()
{
if(listenerSocket!=null)
{
//DatagramSocket.Close()是通过C#中的Dispose()方法公开的。
//下面的调用显式关闭套接字,释放当前绑定到的UDP端口。
Dispose();
listenerSocket=null;
}
}
//设置UI以显示多播方案选项。
专用void SetupMulticastScenarioUI()
{
RemoteAddress.Text=远程地址;
ServiceName.Text=ServiceName;
StartListener.Content=“启动侦听器并加入多播组”;
SendMessageButton.IsEnabled=false;
CloseListenerButton.IsEnabled=false;
SendOutput.Text=“”;
}
私有异步void StartListener\u单击(对象发送方,路由目标)
{
listenerSocket=新的DatagramSocket();
listenerSocket.Control.MulticastOnly=true;
等待listenerSocket.BindServiceNameAsync(ServiceName.Text);
//加入多播组以开始接收发送到该组的数据报。
listenerSocket.JoinMulticastGroup(remoteHostname);
listenerSocket.MessageReceived+=MessageReceived;
SendOutput.Text=“侦听端口”+listenerSocket.Information.LocalPort+“并加入到多播组”;
//启用要求我们具有活动侦听套接字的场景步骤。
SendMessageButton.IsEnabled=true;
CloseListenerButton.IsEnabled=true;
outputStream=await listenerSocket.GetOutputStreamAsync(remoteHostname,ServiceName.Text);
writer=新数据编写器(outputStream);
writer.WriteString(“握手”);
等待writer.StoreAsync();
}
私有异步无效发送消息\u单击(对象发送方,路由目标)
{
writer.WriteString(Message.Text);
等待writer.StoreAsync();
}
私有void CloseListener_单击(对象发送方,路由目标)
{
CloseListenerSocket();
//禁用要求我们具有活动侦听套接字的场景步骤。
SendMessageButton.IsEnabled=false;
CloseListenerButton.IsEnabled=false;
SendOutput.Text=“”;
SendOutput.Text=“监听器已关闭”;
}
接收到异步void message(DatagramSocket套接字、DatagramSocketMessageReceivedEventArgs事件参数)
{
//将传入数据报的全部内容解释为字符串。
uint stringLength=eventArguments.GetDataReader().UnsumedBufferLength;
string receivedMessage=eventArguments.GetDataReader().ReadString(stringLength);
wait Dispatcher.RunAsync(CoreDispatcherPriority.Normal,()=>
{
SendOutput.Text=“从远程对等方接收数据(远程地址:”+
eventArguments.RemoteAddress.CanonicalName+,远程端口:+
eventArguments.RemotePort+”:\“”+receivedMessage+“\”;
});
}
}
}
这是主页.xaml的代码

<Page
    x:Class="Client001.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Client001"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">


    <StackPanel>
        <TextBlock>Remote Address:</TextBlock>
        <TextBox x:Name="RemoteAddress" />

        <TextBlock>Service Name:</TextBlock>
        <TextBox x:Name="ServiceName" />

        <Button x:Name="StartListener" Click="StartListener_Click" Margin="0,10,0,0"/>
        <Button x:Name="SendMessageButton" Content="Send 'hello'" Click="SendMessage_Click" Margin="0,10,0,0"/>
        <Button x:Name="CloseListenerButton" Content="Close Listener" Click="CloseListener_Click" Margin="0,10,0,0"/>
        <TextBlock x:Name="SendOutput" TextWrapping="Wrap"  Margin="0,10,0,0"/>
        <TextBox x:Name="Message"></TextBox>
    </StackPanel>

</Page>

远程地址:
服务名称:
更新:经过一番搜索,我发现可能是TTL(生存时间)的问题,但我仍然不知道如何解决这个问题

总之,我该如何实现,无论何时(不是在5秒内)一些客户端发送消息,所有其他客户端都会收到

这个问题似乎已经在最新的WindowsRS1(Build 14393)OS中修复,下面是屏幕截图(Gif):


您可能需要升级操作系统才能解决此问题。

非常感谢您的回答。如果不太麻烦,请看一看问题,看看这个问题是否也解决了。@Stefan如果我回到办公室,我会检查它:)那么,这个答案回答了你的问题吗?:)我只是将Windows 10更新到最新版本,所以我会让你知道。@Stefan如果没有更改,请同时升级VS,确保已安装适用于通用Windows应用程序的最新修补程序和工具Windows 10更新刚刚完成,我再次尝试了该应用程序。我很高兴地通知你,它是有效的。但现在我遇到了另一个问题。当我开始工作时