从数据库中读取100条数据循环发送给客户端。每条数据总长度>8K
组件用TserverSocket and TclientSocket!
客户端如何稳定的、正确的收取每一条数据?我尝试过的方法
1、只是不断用ReceiveBuf,这种方法肯定不行,有粘包现象存在。
2、自定义数据传输协议(定义包头、包体。包头中包括包体长度)这种方法比1要好一些,但是仍然存在有的数据不能正常接受。疑问:
Receivebuf返回值到底是buf的长度还是-1
参见http://www.delphibbs.com/delphibbs/dispq.asp?lid=2140578请有经验的专家回答!不胜感激!也请有相同疑问的dfw顶之!
解决方案 »
- 多层开发的作用是什么?
- 在开一贴送分, 只要告诉明白我就行
- Delphi 中的listbox 和combobox 是否可以设轩成复选框,
- INSERT INTO 问题! 高手请帮忙!!!!!
- 在listbox中,当我选了一条记录后,记录的背景色 是深蓝色的,我如何把颜色变成红色?
- 急急!!!!,我想做一个很简单的排班表,不知哪位兄弟能帮个忙,分、钱相送!
- 100分寻找条码打印的解决方案
- 求助
- delphi 6 安装后执行,出现“无法定位程序输入点@Variants@initialization$qqrv于动态链接库rtl60.bpl上”
- 请教控件安装问题
- 怎么样复制一个 adoQuery 的字段结构到另外一个 adoQuery?
- 怎样汉化FASTREPORT V3.05?
buffer: string; // 全局变量...
var
RecvBuf: array [0..2048] of char; // 局部变量
n, len: Integer;
begin
// 一次读最多2k并放入全局变量中直到读完缓冲区或出错
repeat
len := recv(socket, RecvBuf[0], 2048, 0);
if len < 0 then
// 错误处理
else begin
RecvBuf[len] := #0;
Buffer := Buffer + RecvBuf;
end;
until len <= 0; n := 1;
while (n <= Length(Buffer) - 4) and (PInteger(@Buffer[n])^ + 4 <= length(Buffer)) do // 最少含一个包时
begin
// Buffer[n+4]就是接收到的数据包的起始位置, 数据包长度就是PInteger(@Buffer[n])^
// 这里你可以根据上面的信息处理接收到的一个包
Inc(n, PInteger(@Buffer[n])^+4); // 定位到下一个包
end;
Buffer := copy(Buffer, n, Length(Buffer)); // 删掉已经处理完的整包, 剩下的就是未收完的半个包, 等待下次接收后继续处理
end;
while (n <= Length(Buffer)-3) and ...忘了string的下标从1开始的
var
RecvBuf: string;
...
begin
setlength(RecvBuf, 2048);
repeat
len := Recv(socket, RecvBuf[1], length(recvbuf), 0);
....
Buffer := Buffer + copy(RecvBuf, 1, len);
until len<=0;
...
end;如果仍希望用固定内存作为接收缓冲的话可以这么写:
var
RecvBuf: array [0..2056] of Char;
...
begin
PInteger(@RecvBuf)^ := 2; // 伪造一个string, 引用计数置为2, 防止delphi把它释放掉
repeat
PInteger(@RecvBuf[4])^ := Recv(socket, RecvBuf[8], 2048, 0);
...
Buffer := Buffer + string(@RecvBuf[8]);
until PInteger(@RecvBuf[4])^ <= 0;
...
end;
把接受的数据放入缓存,每次读到一个包的头标志就检查他的包的结束表示,没收到就等待。收到了就处理这个完整的包,处理完了再从缓存中删除。
上
WINSOCK LAN传文件(倚天篇)
WINSOCK史上最经典的例子(屠龙篇)
完全满足你!
---------------------------------------------------------------------------------
PInteger(@RecvBuf)^ := 2; // 伪造一个string, 引用计数置为2, 防止delphi把它释放掉
---------------------------------------------------------------------------------
请问这句代码为什么可以伪造一个string,难道string[1]是从string的地址偏移了四个字节,我原来还以为是一个字节呢!这个引用计数还可以设置为几啊,分别有什么作用?你这个地方是为了防止delphi在什么时候把它释放啊,难道RecvBuf不能坚持到这个函数调用完毕吗?请赐教!