TServerSocket 的 SendStream 问题??? (100分)

  • 主题发起人 主题发起人 truest9
  • 开始时间 开始时间
T

truest9

Unregistered / Unconfirmed
GUEST, unregistred user!
代码如下:
procedure TUDPMainForm.ACMWaveInData(data: Pointer; size: Integer);
//这个ACM控件不断的产生语音数据
var
A:TMemoryStream;
J:Integer;
begin
try
A:=TMemoryStream.Create;
begin
A.WriteBuffer(data^,size);
A.Position:=0;
for J:=0 to ServerSocket1.Socket.ActiveConnections - 1 do
ServerSocket1.Socket.Connections[J].SendStream(A);
end;
finally
A.Free;
end;
end;

问题如下:
1.当一个ClientSocket连接上来时,程序出现一个“exception class WAccessViolation with message 'Access violaton at address 0041CAF7”错误。
注释掉 A.free 这一句后,数据就可以正常发送
2.当超过一个ClientSocket连接上来时,注释掉 A.free 这一句后,问题依然。
请教了
 
呵呵,从来没用过SendStream,我一直是用SendText的
 
SendText很明显是发送字符型,而且发出的数据在接收方那里会乱,即服务器先发一个A,再发一个B,客户机有可能先收到B,再收到A,最常见的是收到一个AB(以上是我自己测试发现的,不代表完全正确)使用用SendStream应该可以解决这个问题
 
先发送a,再发送b,客户端不可能先收到b再收到a,但极有可能收到ab,用sendstream也一样效果。sendstream的作用并不是在接收方可以一次收到完整的发送数据,而是在发送方发送的数据超过发送缓冲区时你可以写OnClientWrite事件(这个事件会在上次发送而发送缓冲区满造成发送失败后,等缓冲区有空闲时触发以便你继续发送上次未发完的数据,针对非阻塞socket)继续发送(注意哦,sendstream也不保证所有数据能一次全部发送出去,如果sendstream返回false你必须写OnClientWrite事件继续发送直到返回true才能释放stream)。
至于sendtext,不必那么教条吧,谁规定sendtext只能发送字符型的?我一般喜欢将string作为buffer来用,因为它有个好处,会自动释放,而且我可以随便改变它的引用计数来欺骗系统是否需要释放。
我喜欢自己写OnClientWrite而不喜欢用sendstream,因为我觉得sendstream中要创建一个stream用完还要释放,而且创建stream时必然要复制要发送的数据到stream中,这些创建、删除、复制步骤都是不必要的(唯一的好处就是OnClientWrite事件中stream.position已经记录下了下次发送的起始位置,你可以直接再次调用sendstream继续发送。我宁可自己记录下次发送位置,从而省下大量创建、删除、复制数据到stream的开销,尤其对大连接数大数据量的服务端程序来说这些开销就很可观了)。
 
说的非常好,很受用
我想我得改动程序了
不过为什么
ServerSocket1.Socket.Connections[J].SendStream(A);
不行,而
ServerSocket1.Socket.SendStream(A);
可以呢?
我想将数据发送给所有的客户端
 
接受答案了.
 
后退
顶部