服务器与wp7的socket通信【转】 http://www.cnblogs.com/linzheng/archive/2011/06/21/2086456.html...

本文介绍如何利用WindowsPhone7的Socket编程接口实现客户端与服务器端的网络通信,通过一个小例子展示了如何使用WindowsPhone7客户端与Windows控制台程序作为服务器端进行消息的发送与接收。
  芒果更新的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
复制代码
<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
{
publicpartialclass MainPage : PhoneApplicationPage
{
public MainPage()
{
InitializeComponent();
}

privatevoid 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异步事件参数的运行实例属性
socketEventArg.UserToken = sock;

try
{
//运行Socket
sock.ConnectAsync(socketEventArg);
}
catch (SocketException ex)
{
thrownew SocketException((int)ex.ErrorCode);
}

}

privatevoid SocketAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e)
{
// 检查是否发送出错
if (e.SocketError != SocketError.Success)
{
if (e.SocketError == SocketError.ConnectionAborted)
{
Dispatcher.BeginInvoke(() => MessageBox.Show("连接超时请重试! "
+ e.SocketError));
}
elseif (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
{
staticclass Program
{

privatestatic AutoResetEvent _flipFlop =new AutoResetEvent(false);

staticvoid 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>
privatestaticvoid 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,
0,
StateObject.BufferSize,
0,
ReceiveCallback,
state);
}

privatestaticvoid 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>
privatestaticvoid 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);
}

privatestaticvoid 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());
}
}
}

publicclass StateObject
{
public Socket Socket;
public StringBuilder StringBuilder =new StringBuilder();
publicconstint BufferSize =10;
publicbyte[] Buffer =newbyte[BufferSize];
publicint TotalSize;
}
}

转载于:https://www.cnblogs.com/songtzu/archive/2013/01/30/2882444.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值