2017/02/06

UDP Socket Communication between PC and Phone

之前針對UDP傳輸功能,分別有寫過C#(參考這篇)以及Android(參考這篇)的版本。
基於之前寫過的基礎,這篇就來寫一下小小的實作結果,以後就可以讓電腦跟手機互相溝通,透過UDP傳輸技術來玩一些應用。
這個實作還是有些限制條件,首先電腦跟手機都必須要在同一個網域裡面(連到同一個WIFI),之後才能透過IP位址來溝通,接下來分別從PC電腦端跟Android Phone手機端來下手。

PC

先來寫電腦端的部分,因為之前就有寫過C#的WPF,這邊就來把它寫得更完整一點,順便讓內容操作更簡單方便一點。
一樣直接先在專案裡面加入以下三個cs檔,namepsace的部分記得改成專案App的名稱

RecieveDataEventArgs.cs
UdpSocketHoster.cs
UdpSocketSender.cs

主要的程式碼裡面,有加上一段顯示電腦端的IP位址,因為每次連WIFI,IP的位址可能都會不一樣,所以加上這個顯示,手機端就可以改要傳送的IP了。

附上主程式碼:

MainWindow.xaml.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Windows;
  9. using System.Windows.Controls;
  10. using System.Windows.Data;
  11. using System.Windows.Documents;
  12. using System.Windows.Input;
  13. using System.Windows.Media;
  14. using System.Windows.Media.Imaging;
  15. using System.Windows.Navigation;
  16. using System.Windows.Shapes;
  17.  
  18. namespace UDPSample
  19. {
  20. public partial class MainWindow : Window
  21. {
  22. UdpSocketHoster myhoster = new UdpSocketHoster();
  23. UdpSocketSender mysender;
  24. String str_ip;
  25.  
  26. public MainWindow()
  27. {
  28. InitializeComponent();
  29. initSocket();
  30. str_ip = GetIPAddress().ToString();
  31. label_ip.Content = "My IP address: " + str_ip;
  32. }
  33.  
  34. // return the first IPv4, non-dynamic/link-local, non-loopback address
  35. public static IPAddress GetIPAddress()
  36. {
  37. IPAddress[] hostAddresses = Dns.GetHostAddresses("");
  38. foreach (IPAddress hostAddress in hostAddresses)
  39. {
  40. if (hostAddress.AddressFamily == AddressFamily.InterNetwork &&
  41. !IPAddress.IsLoopback(hostAddress) && // ignore loopback addresses
  42. !hostAddress.ToString().StartsWith("169.254.")) // ignore link-local addresses
  43. return hostAddress;
  44. }
  45. return null; // or IPAddress.None if you prefer
  46. }
  47.  
  48. public void initSocket()
  49. {
  50. myhoster = new UdpSocketHoster();
  51. myhoster.RecievedData += (o, e) => RecieveData8008(e.Data.ToString());
  52. myhoster.StartListening += (o, e) => Console.WriteLine("Start Hosting...");
  53. myhoster.StopListening += (o, e) => Console.WriteLine("Stop Hosting...");
  54. myhoster.Start(str_ip, 8008);
  55. }
  56.  
  57. public void RecieveData8008(String _data)
  58. {
  59. Dispatcher.BeginInvoke(new Action(() =>
  60. {
  61. label_recv.Content = "Receive: " + _data;
  62. }));
  63. }
  64. private void button_send_a_Click(object sender, RoutedEventArgs e)
  65. {
  66. String IPAddress = tbox_ipaddress.Text;
  67. String mysocket = tbox_sendsocket.Text;
  68.  
  69. mysender = new UdpSocketSender(IPAddress, 8008);
  70. mysender.Send(mysocket);
  71. label_send.Content = "Send " + mysocket + " to " + IPAddress;
  72. }
  73.  
  74. private void Window_Closed(object sender, EventArgs e)
  75. {
  76. myhoster.Stop();
  77. }
  78. }
  79. }

xaml的程式碼:
  1. <Window x:Class="UDPSample.MainWindow"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.         xmlns:local="clr-namespace:UDPSample"
  7.         mc:Ignorable="d"
  8.         Title="MainWindow" Height="350" Width="525" Closed="Window_Closed">
  9.     <Grid>
  10.         <Viewbox  Name="Viewbox1" Stretch="Fill">
  11.             <Canvas x:Name="Canvas_main" Height="400" Width="600">
  12.                 <Label x:Name="label_ip" Content="My IP address" Canvas.Left="100" Canvas.Top="50" FontSize="20"/>
  13.                 <Label x:Name="label_recv" Content="Receive: null" Canvas.Left="100" Canvas.Top="100" FontSize="20"/>
  14.                 <TextBox x:Name="tbox_ipaddress" Canvas.Left="100" TextWrapping="Wrap" Text="172.20.10.5" Canvas.Top="150" FontSize="20" Width="115"/>
  15.                 <TextBox x:Name="tbox_sendsocket" Canvas.Left="250" TextWrapping="Wrap" Text="socket" Canvas.Top="150" FontSize="20" Width="150"/>
  16.                 <Button x:Name="button_send" Content="Send" Canvas.Left="428" Canvas.Top="150" Click="button_send_a_Click" FontSize="20"/>
  17.                 <Label x:Name="label_send" Content="Show send socket" Canvas.Left="100" Canvas.Top="200" FontSize="20"/>
  18.             </Canvas>
  19.         </Viewbox>
  20.     </Grid>
  21. </Window>

電腦端的App執行畫面如下:


可以看到電腦自己的IP位址,Receive就是收到手機傳送過來的字串。
電腦端這邊也可以輸入手機端的IP位址以及要傳送的字串內容,按下Send之後就會傳送到手機端了。

Android Phone

手機端的部分其實直接用之前寫過的Android(參考這篇)的版本就可以,內容已經很完整了。
手機App執行畫面如下:

在手機上一樣可以看到手機本身的IP位址,Receive就是收到來自電腦的字串,而且一樣可以輸入要傳送的電腦IP位址以及字串內容。

這方面的應用很廣,而且實作上很簡單,可以想一些電腦跟手機之間的互動,練習做一些小東西來玩。


沒有留言:

張貼留言