的确是发送的问题。 小数据量,的我认为还是以自定义的一种报文格式把数据合并后,在发送TCP是一种“流”传递方式,也就是说,它发送数据就像流水一样,中间是不分隔的,只要带宽可以,会一口气把数据连贯起来发出去。如 for i = 0 to 99 winsock1.senddata "A" next i 接收方不是100次接收到“A” 接收方会收到一个字符串“AAAAAA……AAAAAA”你可以: 当客户端收到一个信息后,向服务器发回一个“OK”(或别的什么) 当服务器要发送信息时,先检查有无收到上次的“OK”,没有就不发新的,等待 如已经收到上次的“OK”,就将“OK”标志清空,发本次的新信息。但这其实并不是一个十分好的办法,如果你是做聊天程序,最好还是自行设计一个报文的格式,虽然服务器以“流”的方式发送,但客户端依据报文格式,可以将信息一“条”一“条”地分开。 如:每条信息都以“^%%$*&”开头,则两个“^%%$*&”之间的内容为一条信息另外,如果是聊天程序,一般以UDP方式为宜。
楼上说的是,考虑服务器性能,怎么彻底解决我也不知道, 我也有个问题 o 我想知道发送的数据大到多少的时候不适合用TCP
To monica8361(小猪): 对于winsock建立的连接,暂且不论接收的动作是否比发送更复杂些,服务器的运算速度总是无法快到同步接收许多客户端同时发送数据。当然你可以说服别人买一台很昂贵的服务器,但是你可能同时还要说服别人买许多很破的客户端,这样你的软件运行起来或许才更为完善。
确实会存在多次发送的数据会在一次getdate 里。 我想这是vb的原因。 目前可以这样解决: 1、客户端'客户端发送数据后sent=false '服务器响应后sent=true '(在客户端的datarrival里sent=true) wscli.senddata bytes while not sent doevents '超时处理 loop 2、服务端 dataarrival事件里: wssrv.getdata bytes2,vbarry+vbbyte 'msqu保存数据的集合队列 'msqu.id=index'socket id 'msqu.data=bytes2'variant msqu=bytes2 wssrv.sendata sResponse'响应 3、轮循 while msqu.count>0 '处理msqu.data loop
2、服务端 dataarrival事件里: wssrv.getdata bytes2,vbarry+vbbyte 'msqu保存数据的msqu_list的集合队列 msqu.id=index'socket request id msqu.data=bytes2'variant msqu_list.add msqu wssrv.sendata sResponse'响应 3、轮循 while if msqu_list.count>0 then '处理msqu.data end if loop //"同时有很多客户端连接,并连续发送数据,服务器性能会下降,甚至无响应或者死机。" 在大量的循环中加 sleep n'n毫秒值
一次过发过去.另一端则用Split函数分解出来!
注:Split函数VB5是不存在的
客户端采用数据合并不要,因为之前的数据已经有格式了,
采用timer控件比较难控制。
感觉xiyou(溪游)兄的办法较好,可是觉得在没等到客户端返回数据之前的轮询怎么做呢?大家有无好办法?难道都是用Timer控件一次次轮询直道收到值吗?
还有是否可以在本次发的数据前面带上本次数据的长度?
使用Winsock的SendComplete事件!像你现在这种情况不是接收问题!而是发送问题.Winsock传送一条信息需要一些时间的!发送端在SendComplete事件那就可以得知什么时候是发送下一条数据的成熟时了!OK...
服务器的响应也需要一些时间。连续地for循环发送只会导致服务器性能的下降。
我知道是需要一些时间.但似乎与楼主的问题,有些出入吧?
连续地for循环发送会发生楼主这样的情况...
我认为这,不是服务器性能下降引起的!大可以试试用循环发送.看看服务器触发了多少次DataArrival事件就清楚了!
winsock的传送并不是实时的...这与以前曾经说过的关于怎样判断对方断开了.有人说用SendData通知.但,SendData以后,怎么知道服务器收到,并知道你要关闭Winsock呢?当然,做过winsock的人都知道.SendData后,下条语句马上关闭Winsock.则SendData的信息没有被发出去!也就是说,你用循环来发送信息,只会使信息都挤在winsock的缓冲区里!直到winsock有空闲,结果一次就把挤在一起的信息都发出去了!
只有SendComplete事件触发,才能确定Winsock真的把信息发出去了!太过底层的东西我不清楚...还望指教!
http://www.efile.com.cn/eFile/qyii/TestWinSock.rar
测试环境包括
1:服务器,客户端都在一台机器上,一般没有丢包
2:服务器,客户端在同一局域网的两台机器上,有丢包
3:服务器,客户端在互联网上(异地),有严重丢包(网络不稳定)在反复调试后,只能采用一端发包,接受端回包确认的机制来保证.
在没有收到回包确认时,延时重发,用winsock好象只能这样.
小数据量,的我认为还是以自定义的一种报文格式把数据合并后,在发送TCP是一种“流”传递方式,也就是说,它发送数据就像流水一样,中间是不分隔的,只要带宽可以,会一口气把数据连贯起来发出去。如
for i = 0 to 99
winsock1.senddata "A"
next i
接收方不是100次接收到“A”
接收方会收到一个字符串“AAAAAA……AAAAAA”你可以:
当客户端收到一个信息后,向服务器发回一个“OK”(或别的什么)
当服务器要发送信息时,先检查有无收到上次的“OK”,没有就不发新的,等待
如已经收到上次的“OK”,就将“OK”标志清空,发本次的新信息。但这其实并不是一个十分好的办法,如果你是做聊天程序,最好还是自行设计一个报文的格式,虽然服务器以“流”的方式发送,但客户端依据报文格式,可以将信息一“条”一“条”地分开。
如:每条信息都以“^%%$*&”开头,则两个“^%%$*&”之间的内容为一条信息另外,如果是聊天程序,一般以UDP方式为宜。
我也有个问题
o 我想知道发送的数据大到多少的时候不适合用TCP
至于不断发送的问题,我是参照了Web服务器的工作方法!我写过一个winsock下载文件的程序(没有完成).发现,程序与服务器只是在确定文件那里做了一些握手之外就只有服务器向下发送数据,而接收却完全被动的!服务器根本不需要确定你是否收到,它只顾一直发送.SendComplete事件的触发,是Winsock告诉程序,上一个发送动作已完成了.我就这样想出来的.
在问题里,你是使用循环来发送的.就像我回复那样,Winsock传送不是实时的,它有一个缓冲.到了特定情况(周期吧?)才会把缓冲里的东西发送出去!使用循环,会导致缓冲内的数据叠加.到了winsock的周期,它就一次把缓冲里的数据都发送出去了!
在单机里的情况与网络的情况有很大的区别.网络的API我不认识,到现在还只会用Winsock控件.所以,它的内部工作是怎样实在不清楚.
对于winsock建立的连接,暂且不论接收的动作是否比发送更复杂些,服务器的运算速度总是无法快到同步接收许多客户端同时发送数据。当然你可以说服别人买一台很昂贵的服务器,但是你可能同时还要说服别人买许多很破的客户端,这样你的软件运行起来或许才更为完善。
我想这是vb的原因。
目前可以这样解决:
1、客户端'客户端发送数据后sent=false
'服务器响应后sent=true
'(在客户端的datarrival里sent=true)
wscli.senddata bytes
while not sent
doevents
'超时处理
loop
2、服务端
dataarrival事件里:
wssrv.getdata bytes2,vbarry+vbbyte
'msqu保存数据的集合队列
'msqu.id=index'socket id
'msqu.data=bytes2'variant
msqu=bytes2
wssrv.sendata sResponse'响应
3、轮循
while msqu.count>0
'处理msqu.data
loop
dataarrival事件里:
wssrv.getdata bytes2,vbarry+vbbyte
'msqu保存数据的msqu_list的集合队列
msqu.id=index'socket request id
msqu.data=bytes2'variant
msqu_list.add msqu
wssrv.sendata sResponse'响应
3、轮循
while
if msqu_list.count>0 then
'处理msqu.data
end if
loop
//"同时有很多客户端连接,并连续发送数据,服务器性能会下降,甚至无响应或者死机。"
在大量的循环中加 sleep n'n毫秒值
正常退出:winsock.close.对方的state属性为"同级人员正在关闭..."详见:MSDN
非正常退出:程序出错,进程被杀.对方的state属性为"错误..."另,还可以从winsock的Error事件里得知更多的信息!也是详见:MSDN :) frankwong(黄梓钿) 问题还没解决?
发送你出错的那部分代码到:[email protected]
代码已经发给您了