Windows Phone 7 网络编程之使用Socket(芒果更新)
2011-06-21 23:35
295 查看
芒果更新的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
cs页面
(2) Socket服务器端的实现,使用Windows的控制台程序。
先来看看演示的效果
(1) Windows Phone 7客户端客户端的实现。
MainPage.xaml
<phone:PhoneApplicationPage x:Class="SocketTest.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"> <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock x:Name="PageTitle" Text="Socket测试" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <TextBlock FontSize="30" Text="主机IP:" Margin="12,23,0,540" HorizontalAlignment="Left" Width="99" /> <TextBox x:Name="Host" InputScope="Digits" HorizontalAlignment="Stretch" Text="192.168.1.102" Margin="110,6,0,523" /> <TextBlock FontSize="30" Text="端口号:" Margin="9,102,345,451" /> <TextBox x:Name="Port" InputScope="Digits" HorizontalAlignment="Stretch" Text="8888" Margin="110,90,0,433" /> <TextBlock FontSize="30" Text="发送的消息内容:" Margin="6,180,157,374" /> <TextBox x:Name="Message" HorizontalAlignment="Stretch" Margin="-6,226,6,300" /> <Button x:Name="SendButton" Content="发送" Click="SendButton_Click" Margin="0,509,12,6" /> <ListBox Height="190" HorizontalAlignment="Left" Margin="-4,313,0,0" Name="listBox1" VerticalAlignment="Top" Width="460" /> </Grid> </Grid> </phone:PhoneApplicationPage>
cs页面
using System; using System.Net; using System.Windows; using Microsoft.Phone.Controls; using System.Text; using System.Net.Sockets; namespace SocketTest { public partial class MainPage : PhoneApplicationPage { public MainPage() { InitializeComponent(); } private void SendButton_Click(object sender, RoutedEventArgs e) { // 判断是否已经输入了IP地址和端口 if (string.IsNullOrEmpty(Host.Text) || string.IsNullOrEmpty(Port.Text)) { MessageBox.Show("麻烦输入以下主机IP和端口号,谢谢!"); return; } //主机IP地址 string host = Host.Text.Trim(); //端口号 int port = Convert.ToInt32(Port.Text.Trim()); //建立一个终结点对像 DnsEndPoint hostEntry = new DnsEndPoint(host, port); //创建一个Socket对象 Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //创建一个Socket异步事件参数 SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs(); //将消息内容转化为发送的byte[]格式 byte[] buffer = Encoding.UTF8.GetBytes(Message.Text); //将发送内容的信息存放进Socket异步事件参数中 socketEventArg.SetBuffer(buffer, 0, buffer.Length); //注册Socket完成事件 socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(SocketAsyncEventArgs_Completed); //设置Socket异步事件参数的Socket远程终结点 socketEventArg.RemoteEndPoint = hostEntry; //将定义好的Socket对象赋值给Socket异步事件参数的运行实例属性 socksocketEventArg.UserToken = sock; try { //运行Socket sock.ConnectAsync(socketEventArg); } catch (SocketException ex) { throw new SocketException((int)ex.ErrorCode); } } private void SocketAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e) { // 检查是否发送出错 if (e.SocketError != SocketError.Success) { if (e.SocketError == SocketError.ConnectionAborted) { Dispatcher.BeginInvoke(() => MessageBox.Show("连接超时请重试! " + e.SocketError)); } else if (e.SocketError == SocketError.ConnectionRefused) { Dispatcher.BeginInvoke(() => MessageBox.Show("服务器端问启动" + e.SocketError)); } else { Dispatcher.BeginInvoke(() => MessageBox.Show("出错了" + e.SocketError)); } //关闭连接清理资源 if (e.UserToken != null) { Socket sock = e.UserToken as Socket; sock.Shutdown(SocketShutdown.Both); sock.Close(); } return; } //检查Socket的当前最后的一个操作 switch (e.LastOperation) { //如果最后的一个操作是连接,那么下一步处理就是发送消息。 case SocketAsyncOperation.Connect: if (e.UserToken != null) { //获取运行中的Socket对象 Socket sock = e.UserToken as Socket; //开始发送 bool completesAsynchronously = sock.SendAsync(e); //检查socket发送是否被挂起,如果被挂起将继续进行处理 if (!completesAsynchronously) { SocketAsyncEventArgs_Completed(e.UserToken, e); } }; break; //如果最后的一个操作是发送,那么显示刚才发送成功的消息,然后开始下一步处理就是接收消息。 case SocketAsyncOperation.Send: //将已成功发送的消息内容绑定到listBox1控件中 Dispatcher.BeginInvoke(() => { listBox1.Items.Add("客户端" + DateTime.Now.ToShortTimeString() + "发送的消息 :" + Message.Text); } ); if (e.UserToken != null) { //获取运行中的Socket对象 Socket sock = e.UserToken as Socket; //开始接收服务器端的消息 bool completesAsynchronously = sock.ReceiveAsync(e); //检查socket发送是否被挂起,如果被挂起将继续进行处理 if (!completesAsynchronously) { SocketAsyncEventArgs_Completed(e.UserToken, e); } } break; //如果是最后的一个操作时接收,那么显示接收到的消息内容,并清理资源。 case SocketAsyncOperation.Receive: if (e.UserToken != null) { //获取接收到的消息,并转化为字符串 string dataFromServer = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred); //获取运行中的Socket对象 Socket sock = e.UserToken as Socket; //将接收到的消息内容绑定到listBox1控件中 Dispatcher.BeginInvoke(() => { listBox1.Items.Add("服务器端" + DateTime.Now.ToShortTimeString() + "传过来的消息:" + dataFromServer); }); } break; } } } }
(2) Socket服务器端的实现,使用Windows的控制台程序。
using System; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; namespace SocketServer { static class Program { private static AutoResetEvent _flipFlop = new AutoResetEvent(false); static void Main(string[] args) { //创建socket,使用的是TCP协议,如果用UDP协议,则要用SocketType.Dgram类型的Socket Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //创建终结点EndPoint 取当前主机的ip IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName()); //把ip和端口转化为IPEndpoint实例,端口号取8888 IPEndPoint localEP = new IPEndPoint(ipHostInfo.AddressList.First(), 8888); Console.WriteLine("本地的IP地址和端口是 : {0}", localEP); try { //绑定EndPoint对像(8888端口和ip地址) listener.Bind(localEP); //开始监听 listener.Listen(10); //一直循环接收客户端的消息 while (true) { Console.WriteLine("等待Windows Phone客户端的连接..."); //开始接收下一个连接 listener.BeginAccept(AcceptCallback, listener); //开始线程等待 _flipFlop.WaitOne(); } } catch (Exception e) { Console.WriteLine(e.ToString()); } } /// <summary> /// 接收返回事件处理 /// </summary> /// <param name="ar"></param> private static void AcceptCallback(IAsyncResult ar) { Socket listener = (Socket)ar.AsyncState; Socket socket = listener.EndAccept(ar); Console.WriteLine("连接到Windows Phone客户端。"); _flipFlop.Set(); //开始接收,传递StateObject对象过去 var state = new StateObject(); state.Socket = socket; socket.BeginReceive(state.Buffer, , StateObject.BufferSize, , ReceiveCallback, state); } private static void ReceiveCallback(IAsyncResult ar) { StateObject state = (StateObject)ar.AsyncState; Socket socket = state.Socket; // 读取客户端socket发送过来的数据 int read = socket.EndReceive(ar); // 如果成功读取了客户端socket发送过来的数据 if (read > 0) { //获取客户端的消息,转化为字符串格式 string chunk = Encoding.UTF8.GetString(state.Buffer, 0, read); state.StringBuilder.Append(chunk); if (state.StringBuilder.Length > 0) { string result = state.StringBuilder.ToString(); Console.WriteLine("收到客户端传过来的消息: {0}", result); //发送数据信息给客户端 Send(socket, result); } } } /// <summary> /// 返回客户端数据 /// </summary> /// <param name="handler"></param> /// <param name="data"></param> private static void Send(Socket handler, String data) { //将消息内容转化为发送的byte[]格式 byte[] byteData = Encoding.UTF8.GetBytes(data); //发送消息到Windows Phone客户端 handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler); } private static void SendCallback(IAsyncResult ar) { try { Socket handler = (Socket)ar.AsyncState; // 完成发送消息到Windows Phone客户端 int bytesSent = handler.EndSend(ar); if (bytesSent > 0) { Console.WriteLine("发送成功!"); } } catch (Exception e) { Console.WriteLine(e.ToString()); } } } public class StateObject { public Socket Socket; public StringBuilder StringBuilder = new StringBuilder(); public const int BufferSize = 10; public byte[] Buffer = new byte[BufferSize]; public int TotalSize; } }
相关文章推荐
- Windows Phone 7 网络编程之使用Socket(芒果更新)
- Windows Phone 7 网络编程之使用Socket(芒果更新)
- Windows Phone 7 网络编程之使用Socket(芒果更新)--转载
- Windows Phone 7 网络编程之使用Socket(芒果更新)
- [Socket网络编程]由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。
- [转载]在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(一)----基础类库部分 .
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务2
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务1[使用IE浏览本页]
- Java网络编程(13):使用Socket类接收和发送数据
- Java网络编程,Socket,ServerSocket使用,TCP,UDP的异同
- Symbian 网络编程之使用Socket API
- linux网络编程之socket(四):使用fork并发处理多个client的请求和对等通信p2p
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架
- python socket网络编程步骤详解(socket套接字使用)
- linux网络编程之socket(四):使用fork并发处理多个client的请求和对等通信p2p
- linux 网络编程:使用两线程实现socket同时收发数据
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(一)----基础类库部分
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(一)
- linux 网络编程:使用两线程实现socket同时收发数据