Windows Phone 7 网络编程之使用Socket(芒果更新)

简介:

芒果更新的Windows Phone 7.1版本的API提供了Socket编程的接口,这给Windows Phone 7的网络开发又添加了一把利器,对于Windows Phone 7上的聊天软件开发是一件非常happy的事情。下面用一个小例子来演示一下Windows Phone 7上的Socket编程。用Windows Phone 7上的客户端程序作为Socket客户端,Windows控制台程序作为服务器端,ip取你电脑本机的ip,端口号用8888,实现了Windows Phone 7客户端向服务器端发送消息和接收消息的功能。

先来看看演示的效果

 

 

 

 

(1) Windows Phone 7客户端客户端的实现。
MainPage.xaml

 

 
  1. <phone:PhoneApplicationPage   
  2.     x:Class="SocketTest.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.  
  16.     <Grid x:Name="LayoutRoot" Background="Transparent"> 
  17.         <Grid.RowDefinitions> 
  18.             <RowDefinition Height="Auto"/> 
  19.             <RowDefinition Height="*"/> 
  20.         </Grid.RowDefinitions> 
  21.  
  22.         <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> 
  23.             <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/> 
  24.             <TextBlock x:Name="PageTitle" Text="Socket测试" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> 
  25.         </StackPanel> 
  26.  
  27.         <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> 
  28.  
  29.             <TextBlock FontSize="30" Text="主机IP:" Margin="12,23,0,540" HorizontalAlignment="Left" Width="99" /> 
  30.             <TextBox x:Name="Host" InputScope="Digits" HorizontalAlignment="Stretch" Text="192.168.1.102" Margin="110,6,0,523" /> 
  31.             <TextBlock FontSize="30" Text="端口号:" Margin="9,102,345,451" /> 
  32.             <TextBox x:Name="Port" InputScope="Digits" 
  33.                        HorizontalAlignment="Stretch" 
  34.                        Text="8888" Margin="110,90,0,433" /> 
  35.             <TextBlock  FontSize="30" Text="发送的消息内容:" Margin="6,180,157,374" /> 
  36.                 <TextBox x:Name="Message" 
  37.                          HorizontalAlignment="Stretch" Margin="-6,226,6,300" /> 
  38.             <Button x:Name="SendButton" 
  39.                         Content="发送" 
  40.                         Click="SendButton_Click" Margin="0,509,12,6" /> 
  41.             <ListBox Height="190" HorizontalAlignment="Left" Margin="-4,313,0,0" Name="listBox1" VerticalAlignment="Top" Width="460" /> 
  42.         </Grid> 
  43.     </Grid> 
  44.  
  45. </phone:PhoneApplicationPage> 

cs页面

 

 
  1. using System;  
  2. using System.Net;  
  3. using System.Windows;  
  4. using Microsoft.Phone.Controls;  
  5. using System.Text;  
  6. using System.Net.Sockets;  
  7.  
  8. namespace SocketTest  
  9. {  
  10.     public partial class MainPage : PhoneApplicationPage  
  11.     {  
  12.         public MainPage()  
  13.         {  
  14.             InitializeComponent();  
  15.         }  
  16.  
  17.         private void SendButton_Click(object sender, RoutedEventArgs e)  
  18.         {  
  19.             // 判断是否已经输入了IP地址和端口  
  20.             if (string.IsNullOrEmpty(Host.Text) || string.IsNullOrEmpty(Port.Text))  
  21.             {  
  22.                 MessageBox.Show("麻烦输入以下主机IP和端口号,谢谢!");  
  23.                 return;  
  24.             }  
  25.             //主机IP地址  
  26.             string host = Host.Text.Trim();  
  27.             //端口号  
  28.             int port = Convert.ToInt32(Port.Text.Trim());  
  29.             //建立一个终结点对像  
  30.             DnsEndPoint hostEntry = new DnsEndPoint(host, port);  
  31.             //创建一个Socket对象  
  32.             Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  
  33.             //创建一个Socket异步事件参数  
  34.             SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();  
  35.             //将消息内容转化为发送的byte[]格式   
  36.             byte[] buffer = Encoding.UTF8.GetBytes(Message.Text);  
  37.             //将发送内容的信息存放进Socket异步事件参数中  
  38.             socketEventArg.SetBuffer(buffer, 0, buffer.Length);  
  39.             //注册Socket完成事件  
  40.             socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(SocketAsyncEventArgs_Completed);  
  41.             //设置Socket异步事件参数的Socket远程终结点  
  42.             socketEventArg.RemoteEndPoint = hostEntry;  
  43.             //将定义好的Socket对象赋值给Socket异步事件参数的运行实例属性  
  44.             socksocketEventArg.UserToken = sock;  
  45.  
  46.             try  
  47.             {  
  48.                 //运行Socket  
  49.                 sock.ConnectAsync(socketEventArg);  
  50.             }  
  51.             catch (SocketException ex)  
  52.             {  
  53.                 throw new SocketException((int)ex.ErrorCode);  
  54.             }  
  55.  
  56.         }  
  57.  
  58.         private void SocketAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e)  
  59.         {  
  60.             // 检查是否发送出错  
  61.             if (e.SocketError != SocketError.Success)  
  62.             {  
  63.                 if (e.SocketError == SocketError.ConnectionAborted)  
  64.                 {  
  65.                     Dispatcher.BeginInvoke(() => MessageBox.Show("连接超时请重试! "  
  66.                     + e.SocketError));  
  67.                 }  
  68.                 else if (e.SocketError == SocketError.ConnectionRefused)  
  69.                 {  
  70.                     Dispatcher.BeginInvoke(() => MessageBox.Show("服务器端问启动"  
  71.                         + e.SocketError));  
  72.                 }  
  73.                 else   
  74.                 {  
  75.                     Dispatcher.BeginInvoke(() => MessageBox.Show("出错了"  
  76.                         + e.SocketError));  
  77.                 }  
  78.  
  79.                 //关闭连接清理资源  
  80.                 if (e.UserToken != null)  
  81.                 {  
  82.                     Socket sock = e.UserToken as Socket;  
  83.                     sock.Shutdown(SocketShutdown.Both);  
  84.                     sock.Close();  
  85.                 }  
  86.                 return;  
  87.  
  88.             }  
  89.  
  90.             //检查Socket的当前最后的一个操作  
  91.             switch (e.LastOperation)  
  92.             {  
  93.                 //如果最后的一个操作是连接,那么下一步处理就是发送消息。  
  94.                 case SocketAsyncOperation.Connect:  
  95.                     if (e.UserToken != null)  
  96.                     {  
  97.                         //获取运行中的Socket对象  
  98.                         Socket sock = e.UserToken as Socket;  
  99.                         //开始发送  
  100.                         bool completesAsynchronously = sock.SendAsync(e);   
  101.                         //检查socket发送是否被挂起,如果被挂起将继续进行处理  
  102.                         if (!completesAsynchronously)  
  103.                         {  
  104.                             SocketAsyncEventArgs_Completed(e.UserToken, e);  
  105.                         }  
  106.                     };  
  107.                     break;  
  108.                 //如果最后的一个操作是发送,那么显示刚才发送成功的消息,然后开始下一步处理就是接收消息。  
  109.                 case SocketAsyncOperation.Send:  
  110.                     //将已成功发送的消息内容绑定到listBox1控件中  
  111.                     Dispatcher.BeginInvoke(() => 
  112.                         {  
  113.                             listBox1.Items.Add("客户端" + DateTime.Now.ToShortTimeString() + "发送的消息 :" + Message.Text);  
  114.                         }  
  115.                         );  
  116.                     if (e.UserToken != null)  
  117.                     {  
  118.                         //获取运行中的Socket对象  
  119.                         Socket sock = e.UserToken as Socket;  
  120.                         //开始接收服务器端的消息  
  121.                         bool completesAsynchronously = sock.ReceiveAsync(e);   
  122.                         //检查socket发送是否被挂起,如果被挂起将继续进行处理  
  123.                         if (!completesAsynchronously)  
  124.                         {  
  125.                             SocketAsyncEventArgs_Completed(e.UserToken, e);  
  126.                         }  
  127.                     }  
  128.                     break;  
  129.                 //如果是最后的一个操作时接收,那么显示接收到的消息内容,并清理资源。  
  130.                 case SocketAsyncOperation.Receive:  
  131.                     if (e.UserToken != null)  
  132.                     {  
  133.                         //获取接收到的消息,并转化为字符串  
  134.                         string dataFromServer = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred);  
  135.                         //获取运行中的Socket对象  
  136.                         Socket sock = e.UserToken as Socket;  
  137.                         //将接收到的消息内容绑定到listBox1控件中  
  138.                         Dispatcher.BeginInvoke(() => 
  139.                         {  
  140.                             listBox1.Items.Add("服务器端" + DateTime.Now.ToShortTimeString() + "传过来的消息:" + dataFromServer);  
  141.                         });  
  142.                     }  
  143.                     break;   
  144.             }  
  145.         }  
  146.     }  

(2) Socket服务器端的实现,使用Windows的控制台程序。

 

 
  1. using System;  
  2. using System.Linq;  
  3. using System.Net;  
  4. using System.Net.Sockets;  
  5. using System.Text;  
  6. using System.Threading;  
  7.  
  8. namespace SocketServer  
  9. {  
  10.     static class Program  
  11.     {  
  12.  
  13.         private static AutoResetEvent _flipFlop = new AutoResetEvent(false);  
  14.  
  15.         static void Main(string[] args)  
  16.         {  
  17.             //创建socket,使用的是TCP协议,如果用UDP协议,则要用SocketType.Dgram类型的Socket  
  18.             Socket listener = new Socket(AddressFamily.InterNetwork,  
  19.                 SocketType.Stream,  
  20.                 ProtocolType.Tcp);  
  21.  
  22.             //创建终结点EndPoint  取当前主机的ip  
  23.             IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());  
  24.             //把ip和端口转化为IPEndpoint实例,端口号取8888  
  25.             IPEndPoint localEP = new IPEndPoint(ipHostInfo.AddressList.First(), 8888);  
  26.  
  27.             Console.WriteLine("本地的IP地址和端口是 : {0}", localEP);  
  28.  
  29.             try  
  30.             {  
  31.                 //绑定EndPoint对像(8888端口和ip地址)  
  32.                 listener.Bind(localEP);  
  33.                 //开始监听  
  34.                 listener.Listen(10);  
  35.                 //一直循环接收客户端的消息  
  36.                 while (true)  
  37.                 {  
  38.                     Console.WriteLine("等待Windows Phone客户端的连接...");  
  39.                     //开始接收下一个连接  
  40.                     listener.BeginAccept(AcceptCallback, listener);  
  41.                     //开始线程等待  
  42.                     _flipFlop.WaitOne();  
  43.                 }  
  44.             }  
  45.             catch (Exception e)  
  46.             {  
  47.                 Console.WriteLine(e.ToString());  
  48.             }  
  49.  
  50.         }  
  51.  
  52.         /// <summary> 
  53.         /// 接收返回事件处理  
  54.         /// </summary> 
  55.         /// <param name="ar"></param> 
  56.         private static void AcceptCallback(IAsyncResult ar)  
  57.         {  
  58.             Socket listener = (Socket)ar.AsyncState;  
  59.             Socket socket = listener.EndAccept(ar);  
  60.  
  61.             Console.WriteLine("连接到Windows Phone客户端。");  
  62.  
  63.             _flipFlop.Set();  
  64.  
  65.             //开始接收,传递StateObject对象过去  
  66.             var state = new StateObject();  
  67.             state.Socket = socket;  
  68.             socket.BeginReceive(state.Buffer,  
  69. ,  
  70.                 StateObject.BufferSize,  
  71. ,  
  72.                 ReceiveCallback,  
  73.                 state);  
  74.         }  
  75.  
  76.         private static void ReceiveCallback(IAsyncResult ar)  
  77.         {  
  78.             StateObject state = (StateObject)ar.AsyncState;  
  79.             Socket socket = state.Socket;  
  80.  
  81.  
  82.             // 读取客户端socket发送过来的数据  
  83.             int read = socket.EndReceive(ar);  
  84.  
  85.             // 如果成功读取了客户端socket发送过来的数据  
  86.             if (read > 0)  
  87.             {  
  88.                 //获取客户端的消息,转化为字符串格式  
  89.                 string chunk = Encoding.UTF8.GetString(state.Buffer, 0, read);  
  90.                 state.StringBuilder.Append(chunk);  
  91.  
  92.                 if (state.StringBuilder.Length > 0)  
  93.                 {  
  94.                     string result = state.StringBuilder.ToString();  
  95.                     Console.WriteLine("收到客户端传过来的消息: {0}", result);  
  96.                     //发送数据信息给客户端  
  97.                     Send(socket, result);  
  98.                 }  
  99.             }  
  100.         }  
  101.  
  102.  
  103.         /// <summary> 
  104.         /// 返回客户端数据  
  105.         /// </summary> 
  106.         /// <param name="handler"></param> 
  107.         /// <param name="data"></param> 
  108.         private static void Send(Socket handler, String data)  
  109.         {  
  110.  
  111.             //将消息内容转化为发送的byte[]格式  
  112.             byte[] byteData = Encoding.UTF8.GetBytes(data);  
  113.  
  114.             //发送消息到Windows Phone客户端  
  115.             handler.BeginSend(byteData, 0, byteData.Length, 0,  
  116.                 new AsyncCallback(SendCallback), handler);  
  117.         }  
  118.  
  119.         private static void SendCallback(IAsyncResult ar)  
  120.         {  
  121.             try  
  122.             {  
  123.                 Socket handler = (Socket)ar.AsyncState;  
  124.                 // 完成发送消息到Windows Phone客户端  
  125.                 int bytesSent = handler.EndSend(ar);  
  126.                 if (bytesSent > 0)  
  127.                 {  
  128.                     Console.WriteLine("发送成功!");  
  129.                 }  
  130.             }  
  131.             catch (Exception e)  
  132.             {  
  133.                 Console.WriteLine(e.ToString());  
  134.             }  
  135.         }  
  136.     }  
  137.  
  138.     public class StateObject  
  139.     {  
  140.         public Socket Socket;  
  141.         public StringBuilder StringBuilder = new StringBuilder();  
  142.         public const int BufferSize = 10;  
  143.         public byte[] Buffer = new byte[BufferSize];  
  144.         public int TotalSize;  
  145.     }  

 

本文转自linzheng 51CTO博客,原文链接:http://blog.51cto.com/linzheng/1078573


相关文章
|
24天前
|
存储 网络协议 Ubuntu
【C++网络编程】Socket基础:网络通讯程序入门级教程
【C++网络编程】Socket基础:网络通讯程序入门级教程
42 7
|
24天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
24天前
|
程序员 开发者 Python
Python网络编程基础(Socket编程) 错误处理和异常处理的最佳实践
【4月更文挑战第11天】在网络编程中,错误处理和异常管理不仅是为了程序的健壮性,也是为了提供清晰的用户反馈以及优雅的故障恢复。在前面的章节中,我们讨论了如何使用`try-except`语句来处理网络错误。现在,我们将深入探讨错误处理和异常处理的最佳实践。
|
24天前
|
Python
Python网络编程基础(Socket编程) 使用try-except处理网络错误
【4月更文挑战第11天】在网络编程中,错误处理和异常管理是非常重要的部分。网络操作经常因为各种原因而失败,比如网络断开、服务器无响应、地址不正确等。因此,学会如何使用Python的异常处理机制来捕获和处理这些错误,是编写健壮的网络应用的关键。
|
25天前
|
网络协议 网络安全 Python
Python网络编程基础(Socket编程) 错误处理和异常
【4月更文挑战第10天】网络编程涉及到很多复杂的操作和潜在的风险,如连接失败、数据丢失、超时等问题。因此,正确的错误处理和异常捕获是确保网络程序稳定性和可靠性的关键。本章将介绍网络编程中常见的错误和异常,并探讨如何在Python中进行有效的错误处理。
|
25天前
|
存储 Python
Python网络编程基础(Socket编程) UDP 发送和接收数据
【4月更文挑战第10天】对于UDP客户端而言,发送数据是一个相对简单的过程。首先,你需要构建一个要发送的数据报,这通常是一个字节串(bytes)。然后,你可以调用socket对象的`sendto`方法,将数据报发送到指定的服务器地址和端口。
|
26天前
|
存储 Python
Python网络编程基础(Socket编程)UDP客户端编程
【4月更文挑战第9天】在UDP通信中,客户端负责发送数据到服务器,并接收来自服务器的响应。与服务器不同,客户端通常不需要绑定到特定的地址和端口,因为它可以临时使用任何可用的端口来发送数据。下面,我们将详细讲解UDP客户端编程的基本步骤。
|
24天前
|
存储 算法 Linux
【实战项目】网络编程:在Linux环境下基于opencv和socket的人脸识别系统--C++实现
【实战项目】网络编程:在Linux环境下基于opencv和socket的人脸识别系统--C++实现
48 6
|
26天前
|
Kubernetes 网络协议 Python
Python网络编程:从Socket到Web应用
【4月更文挑战第9天】本文探讨Python在网络编程中的应用,包括Socket编程和Web应用开发。Python的`socket`模块支持TCP/IP客户端和服务器,示例展示了一个echo服务器。此外,Python通过Flask、Django等Web框架简化Web应用开发,支持异步Web编程如Tornado和aiohttp。Python也在微服务架构中占有一席之地,适用于构建轻量级、高效的网络服务。
|
23天前
|
网络协议 Linux Python
Python网络编程基础(Socket编程)epoll在Linux下的使用
【4月更文挑战第12天】在上一节中,我们介绍了使用`select`模块来实现非阻塞IO的方法。然而,`select`模块在处理大量并发连接时可能会存在性能问题。在Linux系统中,`epoll`机制提供了更高效的IO多路复用方式,能够更好地处理大量并发连接。