DGRAM(UDP) チャット UdpClientクラス版

### <font  color="6495ed">1.概要</F>
- 右下のボックスに相手のIPaddr、PORTはお互いたすき掛けにして設定ボタン。
- 同一端末で試験する場合は localhost指定も可。
- F.W.の設定が必要な場合有り。通常、ポップアップで通信を許可するか出るがプログラムを個別指定しないと駄目な場合がある。
- Socketクラスをラッピングした簡易版のUdpClientクラスを使用。(TCP/IPで)多数の接続をするにはsocketクラスが良いらしいが、かなり面倒な実装となる。余程の事が無い限り簡易版で十分。
- 画面とは違い、送信元アドレスを表示する様に改変してあります↓。
- 「remoteEP.Address + " 受信:" + rcvMsg);」

### <font  color="6495ed">2.UDP(DGRAM)の特徴等</F>
- UDPは接続の概念がない、データが無事届くかの保証もない。
- 音声、動画のストリーミング等データが多少欠落しても良いようなケースで使用。
- SOCK_STREAM,DGRAMはOSI参照モデル第4層で扱われる為、第6,7層のhttpよりきめ細かい制御が可能。

### <font  color="6495ed">3.通信中画面</F>
![RD.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/a963b67b-e4cd-171f-fe6f-809594fa4f65.jpeg)
## <font  color="6495ed">4.WPF C#</F>
```c#
// SOCK_DGRAM 1:1 2023.09 (c)inf102 
using System;
using System.Net;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace WPF_UDP1 {

    public partial class MainWindow : Window {
        
        public string SENDIpAddr;
        public int    SendPort;
        public int    RcvPort;
        
        public System.Net.Sockets.UdpClient SendUdp = new System.Net.Sockets.UdpClient();

        public MainWindow() {
            InitializeComponent();
           
        }

        public async void Rcv(){ 

            //UdpClientを作成し、ローカルエンドポイントにバインドする
            System.Net.IPEndPoint localEP    =new System.Net.IPEndPoint(IPAddress.Any, RcvPort);
            System.Net.Sockets.UdpClient UDP =new System.Net.Sockets.UdpClient(localEP);
            System.Net.IPEndPoint remoteEP   =null;

            _= Task.Run(() => {    
                while(true){
                    byte[] rcvBytes = UDP.Receive(ref remoteEP);
                    string rcvMsg = System.Text.Encoding.UTF8.GetString(rcvBytes);
                    
                    this.Dispatcher.Invoke((Action)(() =>{
                        LIST1.Items.Add(remoteEP.Address + " 受信:" + rcvMsg);
               
                        // LSITBOX 最終行に移動
                        var border = VisualTreeHelper.GetChild(LIST1, 0) as Border;
                        var listBoxScroll  = border.Child as ScrollViewer;
                        listBoxScroll.ScrollToEnd();
                     }));
                 }
            });
        }

        // SEND BTN
        private void Button_Click(object sender, RoutedEventArgs e) {
            SendMsg();
        }

        // SEND MAIN
        public async void SendMsg(){
           if (TEXT1.Text=="" ) return;

            byte[] sendBytes = System.Text.Encoding.UTF8.GetBytes(TEXT1.Text);
            await SendUdp.SendAsync (sendBytes, sendBytes.Length, SENDIpAddr, SendPort);
            
            LIST1.Items.Add ("送信:" + TEXT1.Text);
                       
            // LSITBOX 最終行に移動
            var border = VisualTreeHelper.GetChild(LIST1, 0) as Border;
            var listBoxScroll  = border.Child as ScrollViewer;
            listBoxScroll.ScrollToEnd();

            TEXT1.Text="";
            TEXT1.Focus();

        }

        private void TEXT1_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) {
            if (e.Key == Key.Return){
                SendMsg();
            }
        }

        // 設定ボタン
        private void Button_Click_1(object sender, RoutedEventArgs e) {
            SENDIpAddr=IPADDR.Text;
            SendPort=int.Parse(SENDPORT.Text);
            RcvPort=int.Parse(RCVPORT.Text);
            
            Title="[UDP SendAddr " + SENDIpAddr +"] [SendPort "+SendPort + "] [RecvPort "+RcvPort +"]";
            LIST1.Items.Add ("設定完了");
            Rcv();
         }
    }
}
```
## <font  color="6495ed">5.WPF XAML</F>
```xml
<Window x:Class="WPF_UDP1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPF_UDP1"
        mc:Ignorable="d" Title="UDP" Height="350" Width="660">

    <Grid Margin="1,1,1,1" >
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="30"/>

        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="195*"/>
            <ColumnDefinition Width="57"/>
            <ColumnDefinition Width="47"/>
            <ColumnDefinition Width="44"/>
            <ColumnDefinition Width="56"/>
            <ColumnDefinition Width="44"/>
            <ColumnDefinition Width="40"/>
            <ColumnDefinition Width="95"/>
            <ColumnDefinition Width="55"/>
        </Grid.ColumnDefinitions>

        <TextBox x:Name="TEXT1" Height="23" VerticalAlignment="Center" Margin="1,0,1,0" Grid.Column="0" Grid.Row="1" KeyDown="TEXT1_KeyDown" FontSize="16"/>
        <Button Content="送信(_S)"  VerticalAlignment="Center" Grid.Row="1" Height="20" Click="Button_Click" Grid.Column="1" Margin="1,1,1,1" HorizontalAlignment="Left" Width="52"/>
        <ListBox x:Name="LIST1" Grid.ColumnSpan="9" Margin="1,1,1,1" BorderBrush="#FF5D3045" Background="#FF6AA3EF" Foreground="White" FontSize="16"/>
        <Label Content="RcvPORT" FontSize="10" VerticalAlignment="Center" Grid.Row="1" Grid.Column="2"   Height="24" Width="50" Margin="0,0,1,0" HorizontalAlignment="Right"   />
        <TextBox x:Name="RCVPORT" Grid.Row="1" Width="42" TextAlignment="Center" Text="65000" HorizontalAlignment="Center"  VerticalAlignment="Center"  Grid.Column="3" Height="18"/>
        <Label Content="SendPORT"  VerticalAlignment="Center" FontSize="10"  Grid.Row="1"  Grid.Column="4" Height="24"  HorizontalAlignment="Center"  />
        <TextBox x:Name="SENDPORT" Grid.Row="1" HorizontalAlignment="Center" TextAlignment="Center" Width="42" Grid.Column="5" Text="65100" VerticalAlignment="Center" Height="18"  />
        <Label Content="SendIP" FontSize="10" Grid.Column="6" VerticalAlignment="Center"  Grid.Row="1" Height="24"   />
        <TextBox x:Name="IPADDR" TextAlignment="Center" Width="85" Text="172.131.11.128" Grid.Column="7" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center" Height="18"   />
        <Button Grid.Column="8" Content="設定" Margin="1,5,1,5" Grid.Row="1" Click="Button_Click_1" />
    </Grid>
</Window>

```