windowoPhone7.1 Socket编程-实现手机与电脑通信
执行异步的Socket操作的模式包含已下步骤:
1. 配置新的 SocketAsyncEventArgs 对象,或者从应用程序池中获取一个这样的空闲对象。
2.针对该对象设置即将执行的操作所需的属性(例如附加到Completed事件的事件处理程序以及ConnectAsync方法的RemoteEndPoint属性)。
3.调用适当的Socket方法已启动异步操作。
4.如果异步Socket方法返回 true,则说明I/O操作处于挂起状态。操作完成时将引发传递给Socket方法的SocketAsyncEventArgs对象的SocketAsyncEventArgs .ComPleted事件。该事件在事件处理程序中引发时,将查询SocketAsyncEventArgs属性来获取完成状态和Socket操作结果。
5.如果异步Socket方法返回false通,则说明操作是同步完成的。 您可以查詢SocketAsyncEventArgs属性来获取完成状态和Socket操作结果。
6将SocketAsyncEventArgs重用于另一个操作,将它放回到应用程序池中,或者将它丢弃。。
Windowphone程序页面代码-----------------------------------------------------------
<!--ContentPanel - 在此处放置其他内容--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,8,12,-8"> <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="主机IP:" VerticalAlignment="Top" Margin="8,21,0,0" FontSize="26.667"/> <TextBox x:Name="HostText" TextWrapping="Wrap" VerticalAlignment="Top" Margin="94,0,8,0"/> <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="端口号:" VerticalAlignment="Top" Margin="8,104,0,0" FontSize="26.667"/> <TextBox x:Name="PortText" TextWrapping="Wrap" VerticalAlignment="Top" Margin="94,90,8,0"/> <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="发送的消息内容" VerticalAlignment="Top" Margin="12,166,0,0"/> <TextBox x:Name="ContentText" TextWrapping="Wrap" VerticalAlignment="Top" Margin="8,197,8,0"/> <Button x:Name="SendBtn" Content="发送" VerticalAlignment="Bottom" Margin="0,0,8,8" Click="SendBtn_Click" /> <ListBox Margin="12,273,8,92" Name="listboxsendText" /></Grid>
MainPage页面代码---------------
public partial class MainPage : PhoneApplicationPage { // 构造函数 public MainPage() { InitializeComponent(); } private void SendBtn_Click(object sender, RoutedEventArgs e) { if (string.IsNullOrEmpty(HostText.Text)||string.IsNullOrEmpty(PortText.Text)) { MessageBox.Show("请输入主机IP和端口好"); return; } string host = HostText.Text.Trim(); int port = Convert.ToInt32(PortText.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[] buffer = Encoding.UTF8.GetBytes(ContentText.Text); //将发送内内容信息存放进Socket异步事件参数中 socketEventArg.SetBuffer(buffer, 0, buffer.Length); //注册socket完成事件 socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(socketEventArg_Completed); //socketEventArg.Completed += (s, es) => //{ //}; //设置Socket异步事件参数的Socket远程终结点 socketEventArg.RemoteEndPoint = hostEntry; //将定义好的Socket对象赋值给Socket异步事件参数的运行实例属性 socketEventArg.UserToken = sock; try { //运行Socket sock.ConnectAsync(socketEventArg); } catch (SocketException ex) { throw new SocketException((int)ex.ErrorCode); } } void socketEventArg_Completed(object sender, SocketAsyncEventArgs e) { //检测Socket是否发送出差,当前最后的一个操作 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 socks = e.UserToken as Socket; socks.Shutdown(SocketShutdown.Both); socks.Close(); } return; } switch (e.LastOperation) { case SocketAsyncOperation.Connect: if (e.UserToken != null) { Socket socket = e.UserToken as Socket; bool completesAsynchronously = socket.SendAsync(e); //检测Socket发送是否被挂起,如果被挂起将继续进行处理 if (!completesAsynchronously) { socketEventArg_Completed(e.UserToken, e); } } break; case SocketAsyncOperation.None: break; case SocketAsyncOperation.Receive: if (e.UserToken != null) { string dataFromServer = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred); //h获取运行中socket对象 Socket socket = e.UserToken as Socket; //收到信息内容绑定到Listbox控件中 Dispatcher.BeginInvoke(() => { listboxsendText.Items.Add("客户端" + DateTime.Now.ToShortTimeString() + "传来的信息:" + dataFromServer); }); } break; case SocketAsyncOperation.ReceiveFrom: break; case SocketAsyncOperation.Send: Dispatcher.BeginInvoke(() => { listboxsendText.Items.Add("客户端" + DateTime.Now.ToShortTimeString() + "发送的信息:" + ContentText.Text); }); if (e.UserToken != null) { Socket socket = e.UserToken as Socket; //开始接受服务器端的消息 bool completesAsynchronously = socket.ReceiveAsync(e); //检测Socket发送是否呗挂起,如果被挂起将继续进行处理 if (!completesAsynchronously) { socketEventArg_Completed(e.UserToken, e); } } break; case SocketAsyncOperation.SendTo: break; default: break; } } }
Windows控制台程序代码---------------------------------------------
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Threading; namespace SocketServer { 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); IPHostEntry iphostinfo = Dns.Resolve(Dns.GetHostName()); IPEndPoint localEp = new IPEndPoint(iphostinfo.AddressList.First(), 8888); Console.WriteLine("本地的IP地址和端口是:{0}", localEp); try { listener.Bind(localEp); listener.Listen(10); while (true) { Console.WriteLine("等待Windowphone客户端的连接 "); listener.BeginAccept(AccepptCallback,listener); _flipFlop.WaitOne(); } } catch (Exception) { throw; } } private static void AccepptCallback(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, 0, StateObject.BufferSize, 0, ReceiveCallback, state); } //接受返回事件处理 public 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); } } } public static void Send(Socket handler, string data) { //将消息内容转化为发送的byte【】格式 byte[] bytedate = Encoding.UTF8.GetBytes(data); //发送信息到Windowphone客户端 handler.BeginSend(bytedate, 0, bytedate.Length, 0, new AsyncCallback(SendCallback), handler); } public static void SendCallback(IAsyncResult ar) { try { Socket handler = (Socket)ar.AsyncState; //完成信息发送到Windowphone客户端 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; } }
程序运行界面------------------------