成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Windows Phone開發(46):與Socket有個約會

移動開發
在很多情況下,關于Socket的例子,都會做一個聊天程序的,不過,聊天程序要求服務器端和客戶都具有發送和接收數據的功能,這樣會增加實例的難度和代碼長度,不方便入門者閱讀。所以,想了一下,今天咱們不玩聊天的,今天咱們玩遙控飛機,如何?

不知道大家有沒有“談Socket色變”的經歷?就像我一位朋友所說的,Socket這家伙啊,不得已而用之。哈,Socket真的那么恐怖嗎?

其實這話一點也不假,Socket有時候真的不太好操控,也不好維護,但不管怎么樣,我們還是要面對它的,沒準Socket是一位大美女哦。

關于Socket的前世今生就不用我詳述了,關于她的歷史,已經不少人仁志士為她立傳 寫著了,像我們國內的百度百科、互動百科等;全球著名的如維基百科之屬。而且,能加入WP開發的學習行列的,我想各位對.NET的其它技術肯定是有一定基 礎的。我也相信,各位同仁過去一定也寫過與Socket打交道的程序。那么,WP中的Socket又將如何呢?

前提公布答案吧,在WP中使用Socket跟你在其它桌面應用項目如WinForm,WPF等中是一樣的,而且說白了,WP中的Socket只不過是從Silverlight框架中繼承過來的。

.NET的一大優勢就是集成性和統一性都好,這不,你看,無論你是編寫桌面應用程序,還是WP上的應用程序,你會發現,你的學習成本不高,很多東西都是一樣的,而且是相通的。顯然這也是Win8和WP8的應用程序可以整合的原因吧。

在WP中使用Socket要注意以下幾點:

1、WP客戶端應用程序一般不被視為服務器端,因為不能進行綁定本地終結點和監聽連接。但是,收發數據是沒問題D。

2、在WP中的Socket操作(連接、接收以及發送)都是異步進行的。如果希望UI線程和后前線程進行同步,不妨使用System.Threading.ManualResetEvent類,這個東西不好講述,也不好理解。這樣吧,我舉一個例子。

有一天,NC和腦殘因為一件小事鬧沖突,鬧來鬧去還是不能解決,怎么辦呢?于是,NC和腦殘決定來一場比試。兩人約定以跑步方式比試,誰跑得快誰就是勝利者。然而,NC這個人一向比較自負,他相信腦殘絕對跑不過他。這樣,NC就修改了比賽規則:

NC讓腦殘先跑5秒,然后他才開始。

假設NC是主線程,腦殘是后臺線程,現在的情況是:主線程先等待一會兒,讓后臺線程先 執行;后臺線程執行5秒后向主線程發出信號,主線程收到信號后再繼續往下執行。按照故事里的情節:NC先讓腦殘跑5秒鐘,他自己就在起跑線上等待,腦殘跑 了5秒后向NC發出信號,NC看到信號后就開始跑。

下面介紹一個類——SocketAsyncEventArgs。

這個類作為啟動異步操作時傳遞的參數,它可以包含如接收數據的緩沖區、遠程主機、用戶自定義對象等內容,這個類并不復雜,打開“對象瀏覽器”看看就一目了然了。

要設置用于異步接收數據的緩沖區,應調用SetBuffer方法。

好,理論就扯到這兒,其實也沒有什么新的知識點,我只是簡單提一下罷了。

按照慣例,大家都會猜到,理論過后要干什么了,是的,付諸實踐。

在很多情況下,關于Socket的例子,都會做一個聊天程序的,不過,聊天程序要求服務器端和客戶都具有發送和接收數據的功能,這樣會增加實例的難度和代碼長度,不方便入門者閱讀。所以,想了一下,今天咱們不玩聊天的,今天咱們玩遙控飛機,如何?

程序代碼較長,也不便于逐一來講解,這樣吧,為了保持代碼的可讀性,我會把完整的代碼都貼出來,在代碼中我會適當地加上注釋。

先說一下原理,利用Socket進行通訊這不用說了,那是肯定的。功能是通過WP手機客戶端應用程序來控制PC端播放、暫停和停止動畫,而動畫嘛,也不弄那么復雜了,就弄個矩形從左邊移到右邊的動畫吧。

***部分  服務器端

既然要播放動畫,少不了要用WPF了,而且,也方便貼界面布局的代碼。

1、新建WPF應用程序項目。

2、打開MainWindow.xaml文件(默認新建項目后自動打開),輸入以下XAML代碼。

  1. <Window x:Class="MYServer.MainWindow"   
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"   
  4.         Title="服務器端" Height="350" Width="525">   
  5.     <Window.Resources>   
  6.         <Storyboard x:Key="std">   
  7.             <DoubleAnimation Duration="0:0:5"   
  8.                                  Storyboard.TargetName="rect"   
  9.                                  Storyboard.TargetProperty="(Rectangle.RenderTransform).(TranslateTransform.X)"   
  10.                                  To="400"/>   
  11.         </Storyboard>   
  12.     </Window.Resources>   
  13.     <Grid>   
  14.         <Grid.RowDefinitions>   
  15.             <RowDefinition />   
  16.             <RowDefinition Height="Auto" />   
  17.         </Grid.RowDefinitions>   
  18.         <Rectangle x:Name="rect" Grid.Row="0" Width="50" Height="50" Fill="Orange" HorizontalAlignment="Left" VerticalAlignment="Center">   
  19.             <Rectangle.RenderTransform>   
  20.                 <TranslateTransform X="0" Y="0"/>   
  21.             </Rectangle.RenderTransform>   
  22.         </Rectangle>   
  23.         <TextBlock Name="txtDisplay" Grid.Row="1"/>   
  24.     </Grid>   
  25. </Window>   

3、打開MainWindow.xaml.cs文件,完成后臺代碼邏輯。

  1. using System;   
  2. using System.Collections.Generic;   
  3. using System.Linq;   
  4. using System.Text;   
  5. using System.Windows;   
  6. using System.Windows.Controls;   
  7. using System.Windows.Data;   
  8. using System.Windows.Documents;   
  9. using System.Windows.Input;   
  10. using System.Windows.Media;   
  11. using System.Windows.Media.Imaging;   
  12. using System.Windows.Navigation;   
  13. using System.Windows.Shapes;   
  14. using System.Windows.Media.Animation;   
  15. using System.IO;   
  16. using System.Net;   
  17. using System.Net.Sockets;   
  18. namespace MYServer   
  19. {   
  20.     /// <summary>   
  21.     /// MainWindow.xaml 的交互邏輯   
  22.     /// </summary>   
  23.     public partial class MainWindow : Window   
  24.     {   
  25.         Storyboard std = null//演示圖板   
  26.         public MainWindow()   
  27.         {   
  28.             InitializeComponent();   
  29.             // 從資源中把Key為std的Storyboard讀出來   
  30.             std = this.Resources["std"as Storyboard;   
  31.             // 聲明用于監聽連接請求的Socket   
  32.             Socket Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);   
  33.             IPEndPoint local = new IPEndPoint(IPAddress.Any, 1377); //監聽所有網絡接口上的地址   
  34.             Server.Bind(local);// 綁定本地終結點   
  35.             Server.Listen(100);// 偵聽連接請求   
  36.             // 開始異步接受傳入的連接請求   
  37.             Server.BeginAccept(new AsyncCallback(this.AcceptSocketCallback), Server);   
  38.         }   
  39.         /// <summary>   
  40.         /// 接受傳入的Socket的回調   
  41.         /// </summary>   
  42.         private void AcceptSocketCallback(IAsyncResult ia)   
  43.         {   
  44.             Socket _socket = ia.AsyncState as Socket;   
  45.             Socket accptSocket = _socket.EndAccept(ia);   
  46.             try   
  47.             {   
  48.                 IPEndPoint remote = (IPEndPoint)accptSocket.RemoteEndPoint;   
  49.                 // 顯示客戶端的IP   
  50.                 Dispatcher.BeginInvoke(new Action<string>(this.SetIPForText), remote.Address.ToString());   
  51.                 StateObject so = new StateObject();   
  52.                 so.theSocket = accptSocket;   
  53.                 // 開始異步接收消息   
  54.                 accptSocket.BeginReceive(so.Buffer, 0, so.Buffer.Length, SocketFlags.None, new AsyncCallback(this.ReceiveCallback), so);   
  55.             }   
  56.             catch   
  57.             {   
  58.             }   
  59.             // 繼續接受連接請求   
  60.             _socket.BeginAccept(new AsyncCallback(this.AcceptSocketCallback), _socket);   
  61.         }   
  62.         /// <summary>   
  63.         /// 接收消息的回調   
  64.         /// </summary>   
  65.         private void ReceiveCallback(IAsyncResult ia)   
  66.         {   
  67.             StateObject _so = ia.AsyncState as StateObject;   
  68.             Socket _socket = _so.theSocket;   
  69.             try   
  70.             {   
  71.                 int n = _socket.EndReceive(ia);//n就是接收到的字節數   
  72.                 string msg = Encoding.UTF8.GetString(_so.Buffer, 0, n);   
  73.                 // 判斷客戶端發送了啥命令   
  74.                 switch (msg)   
  75.                 {   
  76.                     case "play":   
  77.                         Dispatcher.BeginInvoke(new Action(this.Play), null);   
  78.                         break;   
  79.                     case "pause":   
  80.                         Dispatcher.BeginInvoke(new Action(this.Pause), null);   
  81.                         break;   
  82.                     case "stop":   
  83.                         Dispatcher.BeginInvoke(new Action(this.Stop), null);   
  84.                         break;   
  85.                     default:   
  86.                         break;   
  87.                 }   
  88.             }   
  89.             catch    
  90.             {   
  91.             }   
  92.             _so = new StateObject();   
  93.             _so.theSocket = _socket;   
  94.             // 繼續接收消息   
  95.             _socket.BeginReceive(_so.Buffer,   
  96.                                 0,   
  97.                                 _so.Buffer.Length,   
  98.                                 SocketFlags.None,   
  99.                                 new AsyncCallback(this.ReceiveCallback),   
  100.                                 _so);   
  101.         }   
  102.         /// <summary>   
  103.         /// 顯示客戶端的IP   
  104.         /// </summary>   
  105.         private void SetIPForText(string ip)   
  106.         {   
  107.             this.txtDisplay.Text = "客戶端IP:" + ip;   
  108.         }   
  109.         #region 控制動畫的方法   
  110.         private void Play()   
  111.         {   
  112.             std.Begin();   
  113.         }   
  114.         private void Pause()   
  115.         {   
  116.             std.Pause();   
  117.         }   
  118.         private void Stop()   
  119.         {   
  120.             std.Stop();   
  121.         }   
  122.         #endregion   
  123.     }   
  124.     /// <summary>   
  125.     /// 用于異步Socket操作傳遞的狀態對象   
  126.     /// </summary>   
  127.     public class StateObject   
  128.     {   
  129.         private const int BUFFER_SIZE = 512;   
  130.         public byte[] Buffer { get;  set; }   
  131.         public Socket theSocket { getset; }   
  132.         /// <summary>   
  133.         /// 構造函數   
  134.         /// </summary>   
  135.         public StateObject()   
  136.         {   
  137.             this.Buffer = new byte[BUFFER_SIZE];   
  138.         }   
  139.     }   
  140. }   

別走開,下頁為您介紹WP客戶端

 #p#

第二部分  WP客戶端

1、新建Windows Phone應用程序項目。

2、打開MainPage.xaml文件,參考下面的XAML代碼。

  1. <phone:PhoneApplicationPage    
  2.     x:Class="WPClient.MainPage"   
  3.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   
  4.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"   
  5.     xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"   
  6.     xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"   
  7.     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"   
  8.     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   
  9.     mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"   
  10.     FontFamily="{StaticResource PhoneFontFamilyNormal}"   
  11.     FontSize="{StaticResource PhoneFontSizeNormal}"   
  12.     Foreground="{StaticResource PhoneForegroundBrush}"   
  13.     SupportedOrientations="Portrait" Orientation="Portrait"   
  14.     shell:SystemTray.IsVisible="True">   
  15.     <!--LayoutRoot 是包含所有頁面內容的根網格-->   
  16.     <Grid x:Name="LayoutRoot" Background="Transparent">   
  17.         <Grid.RowDefinitions>   
  18.             <RowDefinition Height="Auto"/>   
  19.             <RowDefinition Height="*"/>   
  20.         </Grid.RowDefinitions>   
  21.         <!--TitlePanel 包含應用程序的名稱和頁標題-->   
  22.         <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">   
  23.             <TextBlock x:Name="ApplicationTitle" Text="我的應用程序" Style="{StaticResource PhoneTextNormalStyle}"/>   
  24.             <TextBlock x:Name="PageTitle" Text="頁面名稱" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>   
  25.         </StackPanel>   
  26.         <!--ContentPanel - 在此處放置其他內容-->   
  27.         <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">   
  28.             <Grid.RowDefinitions>   
  29.                 <RowDefinition Height="auto"/>   
  30.                 <RowDefinition Height="*"/>   
  31.             </Grid.RowDefinitions>   
  32.             <Grid Grid.Row="0">   
  33.                 <Grid.ColumnDefinitions>   
  34.                     <ColumnDefinition Width="Auto" />   
  35.                     <ColumnDefinition />   
  36.                     <ColumnDefinition Width="Auto" />   
  37.                 </Grid.ColumnDefinitions>   
  38.                 <TextBlock Grid.Column="0" VerticalAlignment="Center" Text="服務器IP:" />   
  39.                 <TextBox Name="txtServerIP" Grid.Column="1"/>   
  40.                 <Button Grid.Column="2" Content="連接" Click="onConnect"/>   
  41.             </Grid>   
  42.             <StackPanel Grid.Row="1">   
  43.                 <Button Content="放播動畫" Click="onPlay"/>   
  44.                 <Button Content="暫停動畫" Click="onPause"/>   
  45.                 <Button Content="停止動畫" Click="onStop"/>   
  46.                 <TextBlock Name="txtbInfo" Margin="3,18,3,0"/>   
  47.             </StackPanel>   
  48.         </Grid>   
  49.     </Grid>   
  50.     <!--演示 ApplicationBar 用法的示例代碼-->   
  51.     <!--<phone:PhoneApplicationPage.ApplicationBar>   
  52.         <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">   
  53.             <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="按鈕 1"/>   
  54.             <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="按鈕 2"/>   
  55.             <shell:ApplicationBar.MenuItems>   
  56.                 <shell:ApplicationBarMenuItem Text="菜單項 1"/>   
  57.                 <shell:ApplicationBarMenuItem Text="菜單項 2"/>   
  58.             </shell:ApplicationBar.MenuItems>   
  59.         </shell:ApplicationBar>   
  60.     </phone:PhoneApplicationPage.ApplicationBar>-->   
  61. </phone:PhoneApplicationPage>   

3、打開MainPage.xaml.cs,輸入以下代碼。

  1. using System;   
  2. using System.Collections.Generic;   
  3. using System.Linq;   
  4. using System.Net;   
  5. using System.Windows;   
  6. using System.Windows.Controls;   
  7. using System.Windows.Documents;   
  8. using System.Windows.Input;   
  9. using System.Windows.Media;   
  10. using System.Windows.Media.Animation;   
  11. using System.Windows.Shapes;   
  12. using Microsoft.Phone.Controls;   
  13. using System.Net.Sockets;   
  14. using System.IO;   
  15. using System.Threading;   
  16. namespace WPClient   
  17. {   
  18.     public partial class MainPage : PhoneApplicationPage   
  19.     {   
  20.         Socket mySocket = null;   
  21.         ManualResetEvent MyEvent = null;   
  22.         // 構造函數   
  23.         public MainPage()   
  24.         {   
  25.             InitializeComponent();   
  26.         }   
  27.         protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)   
  28.         {   
  29.             base.OnNavigatedTo(e);   
  30.             if (mySocket == null)   
  31.             {   
  32.                 mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);   
  33.             }   
  34.             if (MyEvent == null)   
  35.             {   
  36.                 MyEvent = new ManualResetEvent(false);   
  37.             }   
  38.         }   
  39.         protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)   
  40.         {   
  41.             if (mySocket != null)   
  42.             {   
  43.                 mySocket.Shutdown(SocketShutdown.Both);   
  44.                 mySocket.Close();   
  45.             }   
  46.             base.OnNavigatedFrom(e);   
  47.         }   
  48.         private void onConnect(object sender, RoutedEventArgs e)   
  49.         {   
  50.             if (mySocket != null)   
  51.             {   
  52.                 SocketAsyncEventArgs connArg = new SocketAsyncEventArgs();   
  53.                 // 要連接的遠程服務器   
  54.                 connArg.RemoteEndPoint = new DnsEndPoint(this.txtServerIP.Text, 1377);   
  55.                 // 操作完成后的回調   
  56.                 connArg.Completed += (sendObj, arg) =>   
  57.                 {   
  58.                     if (arg.SocketError == SocketError.Success) //連接成功   
  59.                     {   
  60.                         Dispatcher.BeginInvoke(() => txtbInfo.Text = "連接成功。");   
  61.                     }   
  62.                     else   
  63.                     {   
  64.                         Dispatcher.BeginInvoke(() =>   
  65.                         {   
  66.                             txtbInfo.Text = "連接失敗,錯誤:" + arg.SocketError.ToString();   
  67.                         });   
  68.                     }   
  69.                     // 向調用線程報告操作結束   
  70.                     MyEvent.Set();   
  71.                 };   
  72.                 // 重置線程等待事件   
  73.                 MyEvent.Reset();   
  74.                 txtbInfo.Text = "正在連接,請等候……";   
  75.                 // 開始異連接   
  76.                 mySocket.ConnectAsync(connArg);   
  77.                 // 等待連接完成   
  78.                 MyEvent.WaitOne(6000);   
  79.             }   
  80.         }   
  81.         private void onPause(object sender, RoutedEventArgs e)   
  82.         {   
  83.             SendCommand("pause");   
  84.         }   
  85.         private void onStop(object sender, RoutedEventArgs e)   
  86.         {   
  87.             SendCommand("stop");   
  88.         }   
  89.         private void onPlay(object sender, RoutedEventArgs e)   
  90.         {   
  91.             SendCommand("play");   
  92.         }   
  93.         private void SendCommand(string txt)   
  94.         {   
  95.             if (mySocket != null && mySocket.Connected)   
  96.             {   
  97.                 SocketAsyncEventArgs sendArg = new SocketAsyncEventArgs();   
  98.                 byte[] buffer = System.Text.Encoding.UTF8.GetBytes(txt);   
  99.                 sendArg.SetBuffer(buffer, 0, buffer.Length);   
  100.                 // 發送完成后的回調   
  101.                 sendArg.Completed += (objSender, mArg) =>   
  102.                     {   
  103.                         // 如果操作成功   
  104.                         if (mArg.SocketError == SocketError.Success)   
  105.                         {   
  106.                             Dispatcher.BeginInvoke(() => txtbInfo.Text = "發送成功。");   
  107.                         }   
  108.                         else   
  109.                         {   
  110.                             Dispatcher.BeginInvoke(() =>   
  111.                                 {   
  112.                                     this.txtbInfo.Text = "發送失敗,錯誤:" + mArg.SocketError.ToString();   
  113.                                 });   
  114.                         }   
  115.                         // 報告異步操作結束   
  116.                         MyEvent.Set();   
  117.                     };   
  118.                 // 重置信號   
  119.                 MyEvent.Reset();   
  120.                 txtbInfo.Text = "正在發送,請等候……";   
  121.                 // 異步發送   
  122.                 mySocket.SendAsync(sendArg);   
  123.                 // 等待操作完成   
  124.                 MyEvent.WaitOne(6000);   
  125.             }   
  126.         }   
  127.     }   
  128. }   

先運行服務器端,再在WP模擬器或真實手機上運行客戶端。

在手機客戶端中,輸入IP地址,點“連接”,連接成功后,就可以發送指令了。

 好的,就到這兒吧,示例的源碼我會上專到“資源”中,有需要的話,大家可以按標題下載。

責任編輯:閆佳明 來源: oschina
相關推薦

2013-07-30 12:37:56

Windows PhoWindows Pho

2010-04-21 17:07:54

Windows Pho

2015-12-11 17:24:50

Androidgradle開發

2013-04-17 14:00:06

Windows PhoWindows Pho

2011-06-07 12:42:15

Windows Pho

2013-04-16 17:02:50

Windows Pho概論

2013-04-19 16:34:56

Windows PhoWindows Pho

2013-07-30 11:18:37

Windows PhoWindows Pho

2013-04-25 16:42:44

Windows Pho反思、建議與忠告

2010-04-08 17:40:23

Windows Pho

2010-04-12 17:32:59

Windows Pho

2010-07-16 15:29:02

Windows Pho

2012-08-16 10:35:50

Windows Pho

2013-04-17 14:47:19

Windows PhoWindows Pho

2011-06-07 11:35:38

Windows Pho

2013-04-17 13:27:04

Windows PhoWindows Pho

2013-07-31 13:03:51

Windows PhoWindows Pho

2013-04-19 16:52:24

Windows PhoWindows Pho

2013-07-31 12:50:39

搭建Windows PWindows Pho

2013-07-31 13:13:50

Windows PhoMVVM模式
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 免费的av网站 | 久久国内精品 | 久久久久国产一区二区三区 | 欧美综合久久久 | 国产一区二区黑人欧美xxxx | 日韩黄色小视频 | 欧美片网站免费 | 国产特一级黄色片 | 欧美激情精品久久久久 | 日韩视频在线免费观看 | 亚洲精品区 | 日韩一区二区三区av | 成人区精品 | 一级大片免费 | 搞av.com| 日日日日日日bbbbb视频 | 久久久久久毛片免费观看 | 久久久精品一区二区三区 | 在线观看国产精品视频 | 久久国产精品视频 | 国产在线一级片 | 黄色片亚洲| 美女视频黄色的 | 亚洲最大看片网站 | 欧美成人一区二区三区 | 在线视频一区二区三区 | 日本在线你懂的 | 四虎影 | 视频在线一区 | 国产精品一区视频 | 国产综合久久久久久鬼色 | 精品欧美乱码久久久久久 | 狠狠热视频 | 国产精品久久久久久久岛一牛影视 | 国产精品美女在线观看 | 久久国产精品亚洲 | av一区在线观看 | 好姑娘影视在线观看高清 | 久久这里有精品 | 91xx在线观看 | 国产成人精品一区二三区在线观看 |