Socket 每次能读多少数据?(200分)

  • 主题发起人 主题发起人 CJ
  • 开始时间 开始时间
1.你还好,我至今还在150名外,最近杀了一些贴,可全是一些老不回应,舍不得给分的主
2.没成功的话...grin,不知有没有扣分的说法?
 
扣分?!! 别吓我。。。。。
 
>当然这里必须保证这个onread不会重入。
这个怎么保证呢?
>极端的情况是你在两次onread之间没有读取前次数据,以至丢失数据.
这个怎么解决?我晓得放个二级缓冲,不过,你的意思是不是在第一次OnRead未触发前,
或者还没把数据加入缓冲之前,第二个OnRead已经被触发,且未被响应,导致数据丢失?
如果是,怎么解决?
我做的是lan应用,且目前在单机运行,所以可能发生类似问题,不过总不能让用户把他
的100m网改建为10m吧?

我目前如此打算,我已经预计到会有类似问题,所以在发送前有定义本次发送长度的地方
是不是可以用类似的方法解决?

var
StrTmpBuffer:String
IntTmpLength:Integer;
...
Implement
...
procedure TForm1.ClientSocket1OnRead...
begin
StrTmpBuffer := ReceiveText + StrTmpBuffer;
if length(StrTmpBuffer) >= IntTmpLength then
ProcessData(StrTmpBuffer);
end;
疑问:
1、会有次序颠倒吗?我知道tcp包会有的,但是重组会不会好呢?
2、会不会把第一次发的后半部分和第二次发的头部分和成一个OnRead里?

暂时没有时间调试,忙着找工作,呵呵……
 
1)用个公共变量标志一下可以吗?实际应该使用信号量啊 但那几个函数我还没
有时间去看。。:)
if isreading=true then
begin
isreading:=true;
........

isreading:=false;
end;
2)第一次OnRead未触发前,
或者还没把数据加入缓冲之前,第二个OnRead已经被触发
这应该不会出现的,否则delphi带的这个socket控件就是一个笑话了
3)绝对(99.999999999999999999999999999999%)不会出现乱序
4)会不会把第一次发的后半部分和第二次发的头部分和成一个OnRead里
这个可能性存在 但可以解决 方法我前面说了





 
没有试过,仅供参考:
这个问题dfw很久以前讨论过,如何完整地接收到数据
方法好象是这样:
用stream的方式,先发送一个size,然后在一个循环里把stream写到buffer里,直到
超出size为止
接收也是一样,先收到size,然后在循环里把buffer读取到stream,直到超出size
有人给出了C代码。
直接用sendtext发大数据似乎是不太好的。
 
前面分段发送的都很正常
发到最后一小段数据很容易出错的。
大量数据应该用block+thread来做
 
我基本完整的解决了问题,方法如下:
1、由于事先有预料会发生类似问题,我定义了自己的结构如下:
1-4bit 命令代码,5-8bit,参数1长度,9-13bit,参数2长度,以后为参数实体。
2、定义以下函数:
function ValidMsg(Msg:String):Boolean;是否有完整信息
function MsgLen(Msg:String):Integer;当前Msg的长度
function TrimFirst(var msg:String):String;返回当前记录并在总缓冲中去处之
3.定义二级缓冲 TmpBuffer:String;初试为空
4.OnRead中类似代码:
TmpBuffer := TmpBuffer + Socket.ReceiveText;
while ValidMsg(TmpBuffer) do
begin
Msg := TrimFirst(TmpBuffer);
ProcessMsg(Msg);
end;
5、基本解决问题了,不过我知道while部分最好教给线程来完成。不过,问题比我想像中
要复杂的多了(我以前以为一个send对应一个read,多简单……)所以,他老人家出的价
已经不够开第二个线程了(CJ好黑,呵呵……),不过,由于要求不高,调试了一下,
程序工作良好且稳定,所以么……嘿嘿

问题到这里基本结束了,谢谢诸位大虾小米,多谢

问题放几天,需要的同志还能参考参考……或者指出还有什么问题……

谁能给出用线程处理的代码?要考虑重入之类,实在麻烦,懒的弄了。给出代码的有分哦
 
照目前的情形,三天内没有什么其它情况 g622 可是全分啊。
 
sonie:

另,请你帮个忙,由于我的网络不通,请把这个贴子帮我贴到你的贴子上.

g66:不好意思了,我其实是想要的分所以才一听要全部给分你才急了,不过你还是别太贪了,分一人一半吧
(或者你干脆大方一点,分全给我,大不了大家都帮你说话,叫CJ不扣你分就是了)。
关于这句话:在接收了一段东西(约为1kbyte左右)后明显有一个等待,是否可理解为ip在此分包?
我还是向大家解释一下,因为我是当时是在linux下实现HTTP客户和FTP,从传输层做起的,当然我用的
socket打开的连接使用了tcp,但放弃了使用他的某些东西,比如说顺序和差错控制等,可能并没有
用到滑动窗口技术(不能肯定,因为如socket打开连接中使用tcp协议机制不太清楚,是缺省就使用
所有的内定的顺序和差错及超时控制还是只是建立一个可靠的连接?)。我在做ftp时(服务和客户)中
自己再做了一个等停来进行顺序差错控制。(如果自己的项目中既做服务端和客户端,而不需考虑过多的
时效的话,我觉得这样做不错。比如说,这边发了一个东西过去,不管多大,然后就等,那边收到如检验
(CRC等)没错,就发一个东西过来说没错,你可以再发,如错了,我就不管是缓冲区溢出还是什么叫对
方重发:本来我是准备再发个贴给CJ建议的),所以我才认为是TCP的原因的可能性不大,从而怀疑到ip.

:以上"理论"纯属个人推测,欢迎批评讨论,强烈呼吁CJ加分



from CJ:
就这样瓜分我的财产了?呵呵,我还没有同意你们怎么分呢。
不过这样的讨论到是很久没有了,唉,基本分分如下:
s and g:80/人 //较高质量的回答
吕:30 //毕竟他第一个转到正题
kaven:10 //在pchome的silent,给了有意的提示
 
等S和G没有<b>表示</b>意见了我就结束它
 
CJ :赶快分分吧 只要有分就没意见 以后还请多多指教
sonie:选择tcp但不使用它的流控基本是不可能的 应该把socket理解为一个面向应用
的接口 强烈建议参看 <TCP/IP详解>卷2
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
835
SUNSTONE的Delphi笔记
S
S
回复
0
查看
765
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部