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

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

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聊天室)

 

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

目录
相关文章
|
3月前
|
Arthas 测试技术
错误提示表明Arthas无法打开目标进程的socket文件
错误提示表明Arthas无法打开目标进程的socket文件
50 2
|
4月前
|
网络协议 安全 Python
socket客户端和服务端,文件的传输
socket 实现,客户端和服务端,文件的传输
42 1
|
安全 PHP
PHP-FPM没有生成socket文件
PHP-FPM没有生成socket文件
136 0
tmpfs以及将socket文件放在tmpfs上可以获得更快访问速度的谣言
tmpfs本质 tmpfs是内存文件系统,在tmpfs目录下的文件本质上都位于内存中(物理内存或者swap分区)。如此可以获得较基于磁盘文件系统更快的文件访问速度。
1322 0
|
Oracle 关系型数据库 数据库
Python远程操作Oracle实现一键备份还原数据库演示,利用socket进行imp、exp一键导入导出oracle数据库dmp文件
Python远程操作Oracle实现一键备份还原数据库演示,利用socket进行imp、exp一键导入导出oracle数据库dmp文件
317 0
Python远程操作Oracle实现一键备份还原数据库演示,利用socket进行imp、exp一键导入导出oracle数据库dmp文件
|
存储 缓存 数据可视化
可视化文件消息收发一体化Socket实现V0.1
本设计旨在通过socket的TCP实现不同类型文件的收发,UDP实现消息的收发。 1.1 需求概述 基本需求: 1) 支持发送不同类型的文件(.txt,.doc,.jpg,.exe,.mp3等所有类型) 2) 支持发送字符消息。 3) 支持可视化、直观显示与操作。 4) 支持单机收发、局域网内两台机器收发。
106 0
可视化文件消息收发一体化Socket实现V0.1
|
C++ 缓存 数据可视化
可视化文件消息收发一体化Socket实现V0.1
本设计旨在通过socket的TCP实现不同类型文件的收发,UDP实现消息的收发。
2454 0