现在的位置: 首页 > 综合 > 正文

在silverlight中利用socket发送图片或文件

2011年12月20日 ⁄ 综合 ⁄ 共 2091字 ⁄ 字号 评论关闭

silverlight中的socket通讯支持,让sl开发基于web的聊天工具成为了可能,后来OpenFileDialog,SaveFileDialog的出现,更使得边聊天边传送图片(文件)得以实现,最新的SL4中又加入了摄像头支持,也许不久真的可以用silverlight开发出功能强大的视频聊天系统,目前唯一还没有解决的是p2p问题,根据sl3的sdk文档所述: 

 

Socket 类为网络通信提供了一组方法和属性。Socket 类允许您使用 ProtocolType 枚举中所列出的任何一种通信协议执行异步数据传输。当前,Silverlight 上唯一支持的 ProtocolType 是 TCP 协议 (Tcp)。

关于在 Silverlight 中使用套接字的一个限制是:网络应用程序可以连接到的端口范围必须在 4502-4534 范围内。这些是使用套接字从 Silverlight 应用程序进行连接所唯一允许使用的端口。如果连接的目标端口不在此端口范围内,则尝试连接时将会失败。 

 

silverlight中的socket使用的协议目前只有tcp协议,不知道以后会不会增加其它协议。

废话不多说,关于silverlight的socket原理及流程,请参看我博客转贴的【csdn周飞的文章】,其大致流程我画了张图:

 

 

简单点说,我们需要处理三方面的东西:

1.服务端上的策略请求监听(943端口):用于接受silverlight socket客户端首次连接时自动发起的策略请求
2.服务端上的消息数据监听(4502至4534范围中的某一个端口):用于接受socket客户端发送过来的用户数据,并根据实际需要转发(或不处理)
3.silverlight客户端的服务端连接,向服务端发数据,异步接受服务端数据...等

 

园子里webabcd为我们写了一个很不错的socket聊天室demo,我在他的基础上,增加了图片发送及文件发送的演示。注:仅仅是演示,图片解码时还有一些问题,尚无法用于正式应用。以下是运行截图:

 

 

要点:

1.如何判断发过来的数据(byte数组),是文本还是图片?或是文件?
我用了一个比较原始的办法,在byte数组中前后加入了一些特定字符,类似字符串的分隔符,接收完以后,再根据特定字符拆分,然后根据其中的标记位(开发人员可自定义)来确定格式

具体实现可参考我的另一篇文章scoket中的byte消息格式设计

2.发送时,文件或图片如何转化为byte数组?
OpenFileDialog可以将选择后的文件返回一个流,再利用BinaryReader将文件流转化为数组

3.接受时,如何将byte数组还原为文件(或图片),并保存?
利用MemoryStream.write将byte数组变成流,然后再调用bitmap.SetSource设置源,从而得到图片;至于文件保存,SaveFileDialog确定保存的文件名后,也会返回一个流,将接受到的byte数组转化为流,然后保存即可

4.发送的数据如果超过缓冲区大小,一次不能接受完整如何处理?

发送时,前后加上特定字符做为标记位,第一个接收到的字符为特定字符则认为是数据包的开始,如果最后一个字符不是特定字符,说明未接收完整,则继续循环接收,直到最后一个字符遇到特定字符为止。

问题:
图片或文件通过流转化为byte数组后,如果数组本身就包含分隔字符,会导致收到数据后“解码”失败,所以在发送前,我把图片或文件数组中的分隔符替换成其它字符了,但这样会导致还原时图片失真。(2009-11-30更新:关于这个问题的解决办法,事后想了下,问题的出现是由于分隔符重复引起的,可以换一种思路,比如在byte前端明确标注该数据包的长度,类似 ^512^...后面是发送的内容(这里的内容可以是自己定义的复杂对象,利用序列化最终转化为byte[]),这样接受到第一个"^"时认为是开始,第一个与第二个"^"之间的数字即为后面内容流的长度,理论上应该可行)

源代码下载:http://files.cnblogs.com/yjmyzz/SocketChat.rar

调试方法:
1.先启动解决方案中的Server
2.再启动silverlight项目Client
3.测试图片或文件发送时,我在源代码根目录下特意放了一张小图片(test.png)及一个小文件文件(test.txt),方便大家调试

更新:

[2009-11-29]

1.将原来的策略监听与消息监听合二为一,在同一个程序中开了二个线程分别监听

2.解决数据包超过缓冲区大小时的接收问题

3.简化代码,去掉原来的线程调度,改用循环调用实现

4.界面做了微调,更容易操作

 

[2009-12-2]

增加了在线演示地址: http://images.24city.com/jimmy/ChatDemo/

 

[2009-12-16]

将修改后的源代码,发布到开源项目网站CodePlex上了,欢迎更多的人一起完善,详情见 我的第一个开源项目-Silverlight Socket ChatRoom(基于socket机制的silverlight聊天室)

 

转载请注明来自菩提树下的杨过

抱歉!评论已关闭.