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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace UDPSample
{
    public partial class MainWindow : Window
    {
        UdpSocketHoster myhoster = new UdpSocketHoster();
        UdpSocketSender mysender;
        String str_ip;

        public MainWindow()
        {
            InitializeComponent();
            initSocket();
            str_ip = GetIPAddress().ToString();
            label_ip.Content = "My IP address: " + str_ip;
        }

        // return the first IPv4, non-dynamic/link-local, non-loopback address
        public static IPAddress GetIPAddress()
        {
            IPAddress[] hostAddresses = Dns.GetHostAddresses("");
            foreach (IPAddress hostAddress in hostAddresses)
            {
                if (hostAddress.AddressFamily == AddressFamily.InterNetwork &&
                    !IPAddress.IsLoopback(hostAddress) &&  // ignore loopback addresses
                    !hostAddress.ToString().StartsWith("169.254."))  // ignore link-local addresses
                    return hostAddress;
            }
            return null; // or IPAddress.None if you prefer
        }

        public void initSocket()
        {
            myhoster = new UdpSocketHoster();
            myhoster.RecievedData += (o, e) => RecieveData8008(e.Data.ToString());
            myhoster.StartListening += (o, e) => Console.WriteLine("Start Hosting...");
            myhoster.StopListening += (o, e) => Console.WriteLine("Stop Hosting...");
            myhoster.Start(str_ip, 8008);
        }

        public void RecieveData8008(String _data)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                label_recv.Content = "Receive: " + _data;
            }));
        }
        
        private void button_send_a_Click(object sender, RoutedEventArgs e)
        {
            String IPAddress = tbox_ipaddress.Text;
            String mysocket = tbox_sendsocket.Text;

            mysender = new UdpSocketSender(IPAddress, 8008);
            mysender.Send(mysocket);
            label_send.Content = "Send " + mysocket + " to " + IPAddress;
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            myhoster.Stop();
        }
    }
}

xaml的程式碼:
<Window x:Class="UDPSample.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:UDPSample"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" Closed="Window_Closed">
    <Grid>
        <Viewbox  Name="Viewbox1" Stretch="Fill">
            <Canvas x:Name="Canvas_main" Height="400" Width="600">
                <Label x:Name="label_ip" Content="My IP address" Canvas.Left="100" Canvas.Top="50" FontSize="20"/>
                <Label x:Name="label_recv" Content="Receive: null" Canvas.Left="100" Canvas.Top="100" FontSize="20"/>
                <TextBox x:Name="tbox_ipaddress" Canvas.Left="100" TextWrapping="Wrap" Text="172.20.10.5" Canvas.Top="150" FontSize="20" Width="115"/>
                <TextBox x:Name="tbox_sendsocket" Canvas.Left="250" TextWrapping="Wrap" Text="socket" Canvas.Top="150" FontSize="20" Width="150"/>
                <Button x:Name="button_send" Content="Send" Canvas.Left="428" Canvas.Top="150" Click="button_send_a_Click" FontSize="20"/>
                <Label x:Name="label_send" Content="Show send socket" Canvas.Left="100" Canvas.Top="200" FontSize="20"/>
            </Canvas>
        </Viewbox>
    </Grid>
</Window>

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


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

Android Phone

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

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

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


沒有留言:

張貼留言