大佬教程收集整理的这篇文章主要介绍了Silverlight Socket 实现收发信息,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
刚接触Silverlight的时候,除了其异步应用WCF、流媒体、动画效果等方面外,Socket是最另我兴奋的功能。
在Web上实现Socket虽然不是什么新鲜事了,Activex,flash等都可以实现这样的效果,但是Silverlight这样方便的运用Socket让服务器与客户端通信确是我之前没有体验过的。
用它可以做什么?可以连线式的让服务器与客户端交互,而且,是在Web上,那么Web开发游戏,语音,视频聊天等都可以基于Socket功能实现,另外,服务器端是独立出来的,不依赖IIS进程,这样让数据之间的交互更自由。
首先,在进行数据交换之前,我们必须明白Silverlight Socket的一些规矩和原则。
Silverlight客户端的Socket都是异步的,这点很容易明白,另外就是,考虑到Silverlight是应用到Web上的,而Silverlight的Socket自然就有一些安全限制。
每一个请求到服务器端的新的Socket连接会话Silverlight都会先悄悄的用另一个Socket去请求策略文件,这是很多刚接触Silverlight Socket的人感到郁闷的地方,请求策略时,Silverlight会自己发送一个字符串<policy-file-request/>到服务器的943端口,然后你必须在服务器程序里接收该请求,分析是否是策略请求后,发送一个策略文件的字符串给客户端,客户端接收到策略文件后自己分析完后再发送程序员自己写的数据请求。
客户端的策略请求是自动发送的,策略文件的接收和分析也是自动的,是Silverlight自发工作的,不需要程序员手工写代码进行发送接收和分析。
但是,服务器端接收策略请求需要手工完成,程序员必须创建一个Socket监听943端口(该端口是固定的,客户端策略请求固定发送到该端口),然后分析请求过来的数据是否是策略请求,如果是的,那么就读取策略文件,再将该策略文件发送到客户端就可以了。
另外一个限制,Silverlight Socket 数据交换端口必须在4502-4534范围,也就是说,整个Socket将用到两个端口,一个是943用于策略请求,另一个是4502-4534范围的你指定的数据交换端口。
不管你的Socket代码是如何工作,第一次在连接之前,Silverlight都会发送策略请求,只有成功接收到服务器返回的策略文件后,你的Socket代码才能进行工作,所以在第一次连接的时候,实际上Silverlight是进行了两次Socket,第一次请求策略,成功才进行你的Socket,因此,服务器端必要监听两个端口,但是两个监听可以分开在两个线程上工作(两个线程,不是两个进程)。每个会话请求一次策略后,之后的请求就不会再请求策略了,所以他们不能是线性的工作,而是两个独立的监听,否则会阻塞。
我的服务器端的策略监听和数据监听是用的两个子线程运行,而MS的示例是用的异步方法,都是为了不相互阻塞,用MS的方式也许更有效率些,而我是为了让代码更容易理解。
客户端实现了将文本框的内容发送到服务器端,然后服务器收到后显示出来,然后发回一句字符串,关闭连接,客户端收到服务器端的信息后也关闭连接。就这么简单
好后,具体看看示例,说明很详细。
客户端
建立一个Silverlight项目
XAML
<UserControl x:Class="SilverlightTest.socket1"
xmlns="http://scheR_258_11845@as.microsoft.com/client/2007"
xmlns:x="http://scheR_258_11845@as.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" BACkground="White" ShowGridLines="True">
<Grid.RowDeFinitions >
<RowDeFinition />
</Grid.RowDeFinitions>
TextBox x:Name="txtToSend" Grid.Row="0"/>
Button Grid.Row="1" Click="OnSend" Content="Send" Margin="20" />
</Grid>
</UserControl>
代码:
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.Media.Animation;
using System.Threading;
using System.Text;
namespace SilverlightTest
public partial class Socket1 : @H_871_301@UserControl
//定义一个可在全局使用的Socket
System.Net.sockets.@H_871_301@Socket socket;
//定义一个同步上下文类,用来将子线程的操作调度到主线程上以可控制UI属性。
@H_871_301@SynchronizationContext syn;
void OnSend(object sender, @H_871_301@EventArgs args)
//定义一个字节数组,并将文本框的的类容转换为字节数组后存入
byte[] bytes = @H_871_301@Encoding.UTF8.GetBytes(txtToSend.Text);
//显示信息,可不要。
txtToSend.Text += "/r/nDnsSafeHost:"+@H_871_301@Application.Current.Host.source.DnsSafeHost;
//将同步上下文设置在当前上下文(线程,主线程,可控制UI的)
syn = @H_871_301@SynchronizationContext.Current;
//为socket创建示例,并设置相关属性。
socket = new System.Net.sockets.@H_871_301@Socket(@H_871_301@AddressFamily.InterNetwork,175)">SocketType.Stream,@H_871_301@ProtocolType.Tcp);
//定义并实例一个Socket参数
@H_871_301@socketasynceventargs socketArgs = new @H_871_301@socketasynceventargs();
//设置到远程终节点属性(4502端口,为什么是4502,MS的SL通信安全上有)
socketArgs.RemoteEndPoint = new @H_871_301@DnsEndPoint(@H_871_301@Application.Current.Host.source.DnsSafeHost,4502);
socketArgs.Completed += new @H_871_301@EventHandler<@H_871_301@socketasynceventargs>(socketArgs_Completed);
//Socket参数的用户标识,实际上就是一个可以传递的OBjeCT参数。
socketArgS.UserToken = bytes;
socket.ConnectAsync(socketArgs);
void socketArgs_Completed(object sender,175)">socketasynceventargs E)
//当任何一个Socket动作完成,都回调该函数,然后对LastOperation进行判断后继续执行相应的部分
case @H_871_301@SocketAsyncOperation.Connect:
ProcessConnect(E);
case @H_871_301@SocketAsyncOperation.Receive:
ProcessReceive(E);
case @H_871_301@SocketAsyncOperation.Send:
ProcessSend(E);
void ProcessConnect(@H_871_301@socketasynceventargs E)
//当连接成功后,获取Socket参数 e传递过来的用户标识(也就是本示例中用户输入的字符串转换的Byte字节数组)
byte[] bytes = (byte[])e.UserToken;
//设置Socket参数的缓冲区参数,将我们的字节数组设置为Socket的缓冲区。
e.SetBuffer(bytes,bytes.Length);
//同步一下上下文,显示一下当前的状态信息。
syn.Post(GetText,"States:"+e.socketError.ToString()+","+e.LastOperation.ToString());
socket.SendAsync(E);
void ProcessSend(@H_871_301@socketasynceventargs E)
byte[] bytes = new byte[1024];
e.SetBuffer(bytes,bytes.Length);
socket.ReceiveAsync(E);
void ProcessReceive(@H_871_301@socketasynceventargs E)
//在执行好接收后,本地SOCKET的缓冲区就会被服务器发送的数据填充。
//显示下信息,当然也是用同步上下文的方式,在显示信息的时候,就直接将缓冲区的字节数组转换成字符串。
syn.Post(GetText,175)">Encoding.UTF8.GetString(e.buffer,e.buffer.Length)+" and Received" );
//关闭Socket连接
socket.Close();
syn.Post(GetText,21)">"Socket Closed");
void GetText(object str)
txtToSend.Text +="/r/n"+ str.ToString();
}
服务器端,创建一个控制台项目
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Threading;
using System.IO;
namespace consoleApp
class @H_871_301@Program
static void Main(String[] args)
@H_871_301@Console.WriteLine("================Socket服务开启======================");
//建立一个子线程,用于创建Socket来监听策略请求和发送。
@H_871_301@ThreadStart pcts = new @H_871_301@ThreadStart(PolicyThread);
@H_871_301@Thread policythread = new @H_871_301@Thread(pcts);
policythread.Start();
//建立一个子线程,用于创建Socket来监听信息请求和发送。
@H_871_301@ThreadStart infots = new @H_871_301@ThreadStart(InfoThread);
@H_871_301@Thread infothread = new @H_871_301@Thread(infots);
//监听策略请求和发送策略请求方法
//创建一个Socket用来监听943(固定的)端口的策略请求
@H_871_301@Socket policy = new @H_871_301@ProtocolType.Tcp);
policy.bind(new @H_871_301@IPEndPoint(@H_871_301@Ipaddress.Any,943));
policy.Listen(10);
if (policy.blocking)//如果Socket是阻止模式的(这个东西实际上可以用不)
//创建Socket,用来获取监听Socket的第一个Socket链接
@H_871_301@Socket _policy = policy.Accept();
//定义一个字符串,该字符串与Silverlight发送过来的请求字符串一样。
String policyrequestString = "<policy-file-request/>";
//定义一个字节数组
byte[] b = new byte[policyrequestString.Length];
_policy.Receive(b);
String requestString = System.Text.@H_871_301@Encoding.UTF8.GetString(b,b.Length);
//显示客户端发送的字符串
@H_871_301@Console.WriteLine(requestString);
//比对客户端发送过来的字符串是否和之前定义的额定好的策略请求字符串相同,如果相同,说明该请求是一个策略请求。
if (requestString == policyrequestString)
//如果客户端发送的是一个策略请求,服务器发送策略文件到客户端
SendPolicy(_policy);
"Policy File have sended");
//关闭当前连接Socket
_policy.Close();
"not a sure request String!");
//监听信息请求和发送信息方法
//创建一个Socket用于监听4502端口,获取接收客户端发送过来的信息
@H_871_301@Socket socket = new @H_871_301@ProtocolType.Tcp);
socket.bind(new :rgb(43,4502));
socket.Listen(10); //创建Socket,用来获取监听Socket的第一个Socket链接 @H_871_301@Socket
//创建一个空字节数组
_socket.Receive(b2);
//显示接收到的信息
@H_871_301@Console.WriteLine(@H_871_301@Encoding.UTF8.GetString(b2));
//发回一个信息给客户端,该信息是字节数组,所以我们将信息字符串转换成字节数组
_socket.Send(@H_871_301@Encoding.UTF8.GetBytes("This Send Over!!"));
//关闭当前Socket连接
_socket.Close();
static void SendPolicy(@H_871_301@Socket socket)
//创建一个文件流,该文件留指定代开一个策略文件,至于策略文件的格式,MS的Silverlight有详细说明和配置方法
@H_871_301@FileStream fs = new @H_871_301@FileStream(@"D:/WebSites/SilverLight/ConsoleApp/bin/Debug/PolicyFile.xml",175)">FileMode.open);
int length = (int)fs.Length;
byte[] bytes = new byte[length];
//将策略文件流读到上面定义的字节数组中
//其策略文件的字节数组发送给客户端
socket.Send(bytes,length,175)">SocketFlags.NonE);
}
结束,这样就可以创建一个简单的Silverlight Socket收发程序了。其中还有许多需要改进的地方。但是已经很能说明Socket收发的过程和方法了,另外,服务器端最还还是用异步方法进行监听,这样在多并发的时候比较有效率。
以上是大佬教程为你收集整理的Silverlight Socket 实现收发信息全部内容,希望文章能够帮你解决Silverlight Socket 实现收发信息所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。