前段时间写了个远程控制的小程序,这个程序里包含了3个连接:
首先是udp,用来让控制端发送消息到被控制端(被控制端相当于Server)
其次是两个TCP,用来 收发、处理 截屏图片和鼠键输入事件udp为先导--被控制端一经运行就会打开一个udp端口等待客户端发命令过来,致使控制端可方便与服务器端建立和断开联系有6个命令
2个是建立和断开控制端与被控制端的TCP连接
2个是启动和停止服务器端发送图片的线程
2个是启动和停止服务器端接收并处理鼠键事件的线程发送“连接”命令后,控制端与被控制端会通过udp端口建立起两个TCP连接
这socket连接是放在被控制端主程序内的(建立socket连接的时候,服务器会打开一个ServerSocket接收客户端)
被控制端的另外两个线程,则是借助这两个socket连接构造自身发送“断开连接”命令后,前述的两个socket连接会断开掉,控制端与被控制端的2个TCP连接断开发送“截屏”命令后,被控制端就会启动发送图片的线程,不断地向控制端发送截屏图片
同时控制端弹出一个窗口来用于接收被控制端发过来的截图发送“停止截屏”,服务器端发送截屏图片的线程停止,客户端接收截屏图片的子窗体也关闭还有就是“协助”和“停止协助”的命令,就是在客户端接收截屏的窗体上加入一个鼠标和键盘事件的监听,
将事件化为对象用对象流发送出去,在被控制端起一个线程用于接收这些事件对象并进行相应的处理!
程序的功能和基本结构描述完毕,当然还有未能描述清楚的地方!
接下来附上这个项目的地址,有兴趣的可以自己去下载来看看
http://download.csdn.net/source/2934701现在说下我的问题,我发送截图是用的TCP协议!!
我每秒截图20帧,大小为1440*768
每张图片大概200kB左右
局域网测试稍微有点延迟,但能用!
但是我用这个和我一个在广东的同学做测试,则根本都连不上(我在湖南长沙)
他给我的建议是:
①命令改用TCP可靠连接发送
②截图这种极耗费网络资源的用UDP连接发送(增强实时性减小延迟必须的!)

后来我仔细想了想,确实是这样的!
我们学校用的是网通2m的网络
理想状况才能发2mB
而如果按我那个思路的话
200kB*20 == 4MB
这网络确实是背不起!
好了,如果要把这个项目投诸于实用
看来改成用TCP连接发送命令 和 UDP连接发送截图是必须的了现在才到了我的问题!
如何用UDP这种不可靠的连接发送大文件?我试了一下
UDP每个包才能发送64kb大小的数据
没仔细看还以为有那么点意思了
仔细看才发现是小写的b
也就是8kB!!

这也忒小了吧?!这么一来的话?我一张截图再怎么缩小大小和进行压缩
也不能压成8kB呀!
那就是说必须发送成多个DatagramPacket咯
这样一来,UDP又是不可靠的发送,丢了一个包的话
一张图片就变的缺胳膊少腿儿了
甚至图片接收过来什么都显示不出来
而且刚刚有考虑到一个问题
就是后面的图片也许发的比前面的快,反而先显示了出来!
问题真是太多了!
希望有人能给出一个思路解决这个问题!也就是关于设计UDP协议使能快速稳定传输的思路
或者是用TCP连接高效发送图片的思路,也成!
关于UDP这条路线,我还是不怎么看好,其中多了很多自己动手的成分,不是一件简单的事情!
望对此有兴趣的同志,高手、大侠们能给予长期的关注!这个我准备做成一个web版的视频语音服务
嫌分给的太少的,如果能协助我解决这个问题,追加100分,绝不食言!
感谢各位的支持!!

解决方案 »

  1.   

    也就是关于设计UDP协议使能快速稳定传输的思路
    如果想用udp 就别考虑稳定...
    如果想用tcp就别考虑快速
      

  2.   

    如果用UDP传输文件之类的东西,必须自己在上面再封装一层可靠的传输协议。可以参考reliable-udp这个规范(搜索一下RELIABLE UDP PROTOCOL就有)UDP打洞了为了在两台局域网的机器建立好UDP连接,这个过程需要一台公网服务器支持,建立好以后就不再需要公网服务器了,过程大致如下:1、双方都通过UDP与服务器通讯后,网关默认就是做了一个外网IP和端口号 与你内网IP与端口号的映射,这个无需设置的,服务器也不需要知道客户的真正内网IP
    2、用户A先通过服务器知道用户B的外网地址与端口  
    3、用户A向用户B的外网地址与端口发送消息,  
    4、在这一次发送中,用户B的网关会拒收这条消息,因为它的映射中并没有这条规则。  
    5、但是用户A的网关就会增加了一条允许规则,允许接收从B发送过来的消息  
    6、服务器要求用户B发送一个消息到用户A的外网IP与端口号  
    7、用户B发送一条消息,这时用户A就可以接收到B的消息,而且网关B也增加了允许规则  
    8、之后,由于网关A与网关B都增加了允许规则,所以A与B都可以向对方的外网IP和端口号发送消息
      

  3.   

    发送截图这种方式,应该只适用于局域网。
    很显然,它对带宽和响应速度,都有极高的要求。
    楼主想做远程控制,Java貌似也有相关的开源框架,可以考虑一下。UDP传输大文件,应该在UDP一层上面再指定一层应用层的传输协议,以便高效传输。
    楼主的应用场景还要求较高的相应速度,这与语音通信可能要类似。思路:
    1.可将每个文件,按照产生的时间来编号。
    2.将文件按照固定大小进行拆分、编号、发送。
    3.接收端将接收到的文件碎片进行整理、归纳。
    4.文件编号靠前并且丢包率低的文件,对丢失的包进行补传(该功能可省略)。
    5.将接收到的完整文件,进行显示。
          如果文件过于老旧(比如10秒中之前有客户端传过来的),则直接丢弃。打孔。
    这个概念,需要楼主对网络协议有个清醒的认识。
    主要要了解IP协议、UDP协议、TCP协议和NAT协议。
    打孔技术,主要应用在有NAT存在的场景中。我们知道,在网络中,是用IP和PORT来定位通信程序的。
    我们通常将IP和PORT,这一组合称为套接字,也就是Socket。它仿佛就是邮件的地址。
    收发双方,只要拿到了对方的Socket,就可以定位对方,然后进行通信了。在NAT存在的场景中,会将IP地址和PORT进行转换,这样,对方拿到的Socket和你本机获得的Socket,
    在内容上(IP和PORT)就不同了。
    当然,NAT的存在,有着很光辉的作用,它可以解决在IPv6未进行推广应用时,公网IP显著不足的问题。
    如果通信双方中,通信的发起方存在NAT,另一方没有NAT,这是不影响信息传输的。
    因为,发起方,经过NAT以后,到达另一方,虽然,后者拿到的Socket与发起方本身的Socket有所不同,
    但是,当信息的返回过程中,NAT还会进行Socket的还原转换。
    如果通信双方都存在NAT的情况下,发起方无法知道,究竟使用什么Socket才能连接到对方。
    因为NAT的转换规则,不由双方控制,而是由NAT主机自行决定的。
    这样,就需要在公网当中,设置一个没有NAT存在的中介服务器。
    通信双方都首先向他连接,这样,中介服务器,就会拿到,通信双方各自NAT后的Socket了。
    之后,中介服务器将双方NAT后的IP和PORT,分别告诉给对方。
    这样,发起方就可以拿着对方NAT后的Socket,向另一方进行连接、数据传输了。具体解说,网上面灰常多,楼主只要搜索一下,UDP打孔技术,就会有了。
      

  4.   


    楼上的回答的太好了,解决了我很久以来的疑惑!貌似是这样的,请指正一下我的理解:因为公网的IP地址不够用,因此想让中国的每一个学生都有一个独立的公网IP肯定是办不到的!于是诞生了一些“社团、社区服务器”,这些服务器都有一个公网的IP,而且下辖N多个处于特定区域的个人电脑集群。一台机器上可用的TCP端口和UDP端口都各有65536个,而在实际应用的时候,这么多端口是根本用不完的,除了一些常用的端口:比如80端口(负责浏览器),1433端口(SQLServer),邮件端口以及1000来个系统所使用的端口,余下的端口的数量仍然非常之庞大!于是,既然IP地址不够用了,那么就充分利用这些“社团、社区服务器”的端口,比如说,下辖在这个服务器中的一个子个人电脑要浏览网页了,那么他实际上不需要自己的IP地址为公网的IP地址,而只要能让这个社团服务器准确定位到就可以了!等他要浏览网页的时候,它确实会打开80端口,不过不是直接用自己的IP+Port去连接外网上的web服务器请求服务,而是连接到社团服务器,这时候社团服务器会打开一个端口,让下辖的个人电脑的ip+port地址转换为自己的ip+port地址,由自己代理他去访问web服务器,到接收到内容以后,就由自己传递给其下辖的个人电脑。就像小弟要和另一个帮派的小弟发出正式的挑战,他想去喝另一个帮派的老大商议,但是他又不够格,就只能先告知给自己的老大,让自己的老大去和另一个帮派的老大商议,老大们商议完毕后,才会告知小弟他发出的挑战是否已经被认可了,之后要在哪儿哪儿设置擂台...
    最后,在总结一下,也就是让社团服务器的每一个TCP和UDP端口能得到最大化的应用,用同一公网IP地址上端口数量的使用的增加解决公网IP不够用的问题!