- 浏览: 12925636 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
sanrenxing_1:
GoEasy 实时推送支持IE6-IE11及大多数主流浏览器的 ...
WindowsPhone消息推送服务 -
张砚辉:
两侧照片绕Y轴旋转后有锯齿,请问锯齿解决方案,很长时间没解决
自定义带倒影和偏转的超炫Gallery -
knight_black_bob:
能不能把你自己的博客整理下分类下,写了这么多 ,都不知道怎么查 ...
Android_View,ViewGroup,Window之间的关系 -
jeasonyoung:
你这个代码实现在iOS8下应该是滑不动的
UISlider 滑块控件—IOS开发 -
wx_hello:
如果能写个可运行的java程序,不胜感激。。。
rs232串口通信原理
Windows Phone开发(46):与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代码。
<Window x:Class="MYServer.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="服务器端" Height="350" Width="525"> <Window.Resources> <Storyboard x:Key="std"> <DoubleAnimation Duration="0:0:5" Storyboard.TargetName="rect" Storyboard.TargetProperty="(Rectangle.RenderTransform).(TranslateTransform.X)" To="400"/> </Storyboard> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Rectangle x:Name="rect" Grid.Row="0" Width="50" Height="50" Fill="Orange" HorizontalAlignment="Left" VerticalAlignment="Center"> <Rectangle.RenderTransform> <TranslateTransform X="0" Y="0"/> </Rectangle.RenderTransform> </Rectangle> <TextBlock Name="txtDisplay" Grid.Row="1"/> </Grid> </Window>
3、打开MainWindow.xaml.cs文件,完成后台代码逻辑。
using System; using System.Collections.Generic; using System.Linq; using System.Text; 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; using System.Windows.Media.Animation; using System.IO; using System.Net; using System.Net.Sockets; namespace MYServer { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { Storyboard std = null; //演示图板 public MainWindow() { InitializeComponent(); // 从资源中把Key为std的Storyboard读出来 std = this.Resources["std"] as Storyboard; // 声明用于监听连接请求的Socket Socket Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint local = new IPEndPoint(IPAddress.Any, 1377); //监听所有网络接口上的地址 Server.Bind(local);// 绑定本地终结点 Server.Listen(100);// 侦听连接请求 // 开始异步接受传入的连接请求 Server.BeginAccept(new AsyncCallback(this.AcceptSocketCallback), Server); } /// <summary> /// 接受传入的Socket的回调 /// </summary> private void AcceptSocketCallback(IAsyncResult ia) { Socket _socket = ia.AsyncState as Socket; Socket accptSocket = _socket.EndAccept(ia); try { IPEndPoint remote = (IPEndPoint)accptSocket.RemoteEndPoint; // 显示客户端的IP Dispatcher.BeginInvoke(new Action<string>(this.SetIPForText), remote.Address.ToString()); StateObject so = new StateObject(); so.theSocket = accptSocket; // 开始异步接收消息 accptSocket.BeginReceive(so.Buffer, 0, so.Buffer.Length, SocketFlags.None, new AsyncCallback(this.ReceiveCallback), so); } catch { } // 继续接受连接请求 _socket.BeginAccept(new AsyncCallback(this.AcceptSocketCallback), _socket); } /// <summary> /// 接收消息的回调 /// </summary> private void ReceiveCallback(IAsyncResult ia) { StateObject _so = ia.AsyncState as StateObject; Socket _socket = _so.theSocket; try { int n = _socket.EndReceive(ia);//n就是接收到的字节数 string msg = Encoding.UTF8.GetString(_so.Buffer, 0, n); // 判断客户端发送了啥命令 switch (msg) { case "play": Dispatcher.BeginInvoke(new Action(this.Play), null); break; case "pause": Dispatcher.BeginInvoke(new Action(this.Pause), null); break; case "stop": Dispatcher.BeginInvoke(new Action(this.Stop), null); break; default: break; } } catch { } _so = new StateObject(); _so.theSocket = _socket; // 继续接收消息 _socket.BeginReceive(_so.Buffer, 0, _so.Buffer.Length, SocketFlags.None, new AsyncCallback(this.ReceiveCallback), _so); } /// <summary> /// 显示客户端的IP /// </summary> private void SetIPForText(string ip) { this.txtDisplay.Text = "客户端IP:" + ip; } #region 控制动画的方法 private void Play() { std.Begin(); } private void Pause() { std.Pause(); } private void Stop() { std.Stop(); } #endregion } /// <summary> /// 用于异步Socket操作传递的状态对象 /// </summary> public class StateObject { private const int BUFFER_SIZE = 512; public byte[] Buffer { get; set; } public Socket theSocket { get; set; } /// <summary> /// 构造函数 /// </summary> public StateObject() { this.Buffer = new byte[BUFFER_SIZE]; } } }
第二部分 WP客户端
1、新建Windows Phone应用程序项目。
2、打开MainPage.xaml文件,参考下面的XAML代码。
<phone:PhoneApplicationPage x:Class="WPClient.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" shell:SystemTray.IsVisible="True"> <!--LayoutRoot 是包含所有页面内容的根网格--> <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!--TitlePanel 包含应用程序的名称和页标题--> <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock x:Name="ApplicationTitle" Text="我的应用程序" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock x:Name="PageTitle" Text="页面名称" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel> <!--ContentPanel - 在此处放置其他内容--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid Grid.Row="0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <TextBlock Grid.Column="0" VerticalAlignment="Center" Text="服务器IP:" /> <TextBox Name="txtServerIP" Grid.Column="1"/> <Button Grid.Column="2" Content="连接" Click="onConnect"/> </Grid> <StackPanel Grid.Row="1"> <Button Content="放播动画" Click="onPlay"/> <Button Content="暂停动画" Click="onPause"/> <Button Content="停止动画" Click="onStop"/> <TextBlock Name="txtbInfo" Margin="3,18,3,0"/> </StackPanel> </Grid> </Grid> <!--演示 ApplicationBar 用法的示例代码--> <!--<phone:PhoneApplicationPage.ApplicationBar> <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True"> <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="按钮 1"/> <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="按钮 2"/> <shell:ApplicationBar.MenuItems> <shell:ApplicationBarMenuItem Text="菜单项 1"/> <shell:ApplicationBarMenuItem Text="菜单项 2"/> </shell:ApplicationBar.MenuItems> </shell:ApplicationBar> </phone:PhoneApplicationPage.ApplicationBar>--> </phone:PhoneApplicationPage>
3、打开MainPage.xaml.cs,输入以下代码。
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using System.Net.Sockets; using System.IO; using System.Threading; namespace WPClient { public partial class MainPage : PhoneApplicationPage { Socket mySocket = null; ManualResetEvent MyEvent = null; // 构造函数 public MainPage() { InitializeComponent(); } protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { base.OnNavigatedTo(e); if (mySocket == null) { mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); } if (MyEvent == null) { MyEvent = new ManualResetEvent(false); } } protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e) { if (mySocket != null) { mySocket.Shutdown(SocketShutdown.Both); mySocket.Close(); } base.OnNavigatedFrom(e); } private void onConnect(object sender, RoutedEventArgs e) { if (mySocket != null) { SocketAsyncEventArgs connArg = new SocketAsyncEventArgs(); // 要连接的远程服务器 connArg.RemoteEndPoint = new DnsEndPoint(this.txtServerIP.Text, 1377); // 操作完成后的回调 connArg.Completed += (sendObj, arg) => { if (arg.SocketError == SocketError.Success) //连接成功 { Dispatcher.BeginInvoke(() => txtbInfo.Text = "连接成功。"); } else { Dispatcher.BeginInvoke(() => { txtbInfo.Text = "连接失败,错误:" + arg.SocketError.ToString(); }); } // 向调用线程报告操作结束 MyEvent.Set(); }; // 重置线程等待事件 MyEvent.Reset(); txtbInfo.Text = "正在连接,请等候……"; // 开始异连接 mySocket.ConnectAsync(connArg); // 等待连接完成 MyEvent.WaitOne(6000); } } private void onPause(object sender, RoutedEventArgs e) { SendCommand("pause"); } private void onStop(object sender, RoutedEventArgs e) { SendCommand("stop"); } private void onPlay(object sender, RoutedEventArgs e) { SendCommand("play"); } private void SendCommand(string txt) { if (mySocket != null && mySocket.Connected) { SocketAsyncEventArgs sendArg = new SocketAsyncEventArgs(); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(txt); sendArg.SetBuffer(buffer, 0, buffer.Length); // 发送完成后的回调 sendArg.Completed += (objSender, mArg) => { // 如果操作成功 if (mArg.SocketError == SocketError.Success) { Dispatcher.BeginInvoke(() => txtbInfo.Text = "发送成功。"); } else { Dispatcher.BeginInvoke(() => { this.txtbInfo.Text = "发送失败,错误:" + mArg.SocketError.ToString(); }); } // 报告异步操作结束 MyEvent.Set(); }; // 重置信号 MyEvent.Reset(); txtbInfo.Text = "正在发送,请等候……"; // 异步发送 mySocket.SendAsync(sendArg); // 等待操作完成 MyEvent.WaitOne(6000); } } } }
先运行服务器端,再在WP模拟器或真实手机上运行客户端。
在手机客户端中,输入IP地址,点“连接”,连接成功后,就可以发送指令了。
好的,就到这儿吧,示例的源码我会上专到“资源”中,有需要的话,大家可以按标题下载。
相关推荐
iPhone狂:约会iPhone
windows phone 开发 在线教程
对Windows Phone 7应用程序生命周期的深度剖析,在与硬件进行交互和使用Expression Blend来创建更丰富的用户界面方面提供的建议,这些都有助于你学习创建独特而又实用的Windows Phone 7应用程序。
windows phone 开发书籍及资料
Developers are racing to discover how to develop for Windows Phone 7—and there is no quicker resource to help you get up to speed than Windows Phone 7 Recipes. This book covers all aspects of ...
windowsphone开发:类库和案例[借鉴].pdf
Windows Phone(简称:WP)是微软发布的一款手机操作系统,它将微软旗下的Xbox Live游戏、Xbox Music音乐与独特的视频体验集成至手机中。微软公司于2010年10月11日晚上9点30分正式发布了智能手机操作系统Windows ...
内容提要: 本书对WindowsPhoneXNA游戏开发的流程进行了详细的讲解,对其核心内容和开发技巧进行了深入的说明。...本书还针对WindowsPhone8的新特性以及如何将WindowsPhone7游戏向WindowsPhone8上迁移做了详细的说明。
Windows Phone开发-XNA基础
[Packt Publishing] Windows Phone 8 游戏开发教程 (英文版) [Packt Publishing] Windows Phone 8 Game Development (E-Book) ☆ 图书概要:☆ A practical guide to creating games for the Windows Phone 8 ...
在开发Windows Phone应用程序的时候,或多或少会与图片打交道,下面总结下Windows Phone 中处理图片的一些技巧
Windows Phone Blog Menu是一个Silverlight导航控件,看起来像Windows Phone 7。 控件中的tiles链接到web站点在你的博客中使用这个控件可以表达你对WP7的喜爱。 Windows Phone Blog Menu is a Silverlight ...
今天,微软面向开发者正式发布了Windows Phone SDK 7.1开发工具的RTW版 Windows Phone SDK 7.1.1 更新在现有的 Windows Phone SDK 7.1 的基础上提供了更多功能。使用此更新,您可以更加轻松地开发可在 256 MB 设备...
Windows Phone7是微软重新打造windows mobile品牌之后推出的一款产品。
本书适合于Windows Phone 7开发入门的读者,也适合于从其他智能手机平台转向Windows Phone 7平台的读者,同时对于有Windows Phone 7开发经验的读者也极具参考价值。 本书系统论述了Windows Phone 7操作系统的应用...
windows phone7 开发的案例,内有完整的工程项目。
Windows Phone 8 Networking Socket 通信实例, 实现Pc端 手机端 之间的通信
从monotouch和.net开发环境到objective-c和c#开发语言,从基于monotouch进行iphone开发的编程方法到应用程序的发布和销售等,《iPhone高级编程:使用Mono Touch和.NET/C#》涵盖了基于monotouch进行iphone应用程序...
WindowsPhone开发,包含聊天室案例开始,阅读器、天气预报、SignalR
我也把重点从Windows Mobile与Windows Embedded CE慢慢转向Windows Phone的开发。因此编写Silverlight for Windows Phone 7开发系列文章,从简单到深入的讲述Silverlight for Windows Phone 的开发。这个系列主要...