1.概要
- 右下のボックスに相手のIPaddr、PORTはお互いたすき掛けにして設定ボタン。
- 同一端末で試験する場合は localhost指定も可。
- F.W.の設定が必要な場合有り。通常、ポップアップで通信を許可するか出るがプログラムを個別指定しないと駄目な場合がある。
- Socketクラスをラッピングした簡易版のUdpClientクラスを使用。(TCP/IPで)多数の接続をするにはsocketクラスが良いらしいが、かなり面倒な実装となる。余程の事が無い限り簡易版で十分。
- 画面とは違い、送信元アドレスを表示する様に改変してあります↓。
- 「remoteEP.Address + " 受信:" + rcvMsg);」
- ご要望があればストリーム型(TCP/IP)版も作ります。
2.UDP(DGRAM)の特徴等
- UDPは接続の概念がない、データが無事届くかの保証もない。
- 音声、動画のストリーミング等データが多少欠落しても良いようなケースで使用。
- httpより下のOSIレイヤを使用。特にTCP/IPの場合はきめ細かい制御が可能となる。
- メール Webサーバ FTP スマートフォン等の各種通信はほぼ全てソケットを使用。
- SOCK_STREAM,DGRAMはOSI参照モデル第4層で扱われる為、第6,7層のhttpよりきめ細かい制御が可能。
- OSI参照モデルの順番はAPSTND アプストエヌディ で覚えれば簡単。物理層は最後なのは書くまでもない。
3.通信中画面
4.WPF 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();
}
}
}
5.WPF XAML
<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>