ClientSocket控件在SendStream(myStream) 后,myStream是否delphi自己释放了?(100)

A

Andyli

Unregistered / Unconfirmed
GUEST, unregistred user!
看了很多有关ClientSocket的贴子,很大一部分在用ClientSocket控件的SendStream(myStream)后,都在后面加多了myStream.Free,但我在实际用的过程中如果加上myStream.Free一句,则程序会报错,大富翁上也有前辈提到说myStream是由ClientSocket自己管理,sendStream后就释放了,但是那么多贴子都在后面写有myStream.Free,难道说那么多人的代码都有问题??在离线包上随便找一个贴上来,大家谈谈下面代码最后是否要加上Sendstream.Free这句???procedure sendrecord;varsendem :EmpMessage;grecorcount:Byte;recordsize:integer;SendStream :tmemorystream;begin grecorcount:=3; Setlength(sendem.G_record,grecorcount); recordsize:=sizeof(EmpMessage) +grecorcount*sizeof(GoodsRec);//注意这里!! sendem.grecorcount:=grecorcount; sendem.ename:='test'; ......//填完其他的数据 sendem.G_record[0].goodsid:='aaaaaaaaaa'; sendem.G_record[0].goodsname:='bbbbbbbbb'; ...... sendem.G_record[grecorcount].goodsid:='fffffff'; sendem.G_record[grecorcount].goodsname:='zzzzzzzz'; SendStream:=Tmemorystream.create; try Sendstream.write(sendem,recordsize); Sendstream.position:=0; clientsocket.sendStream(sendstream);finally Sendstream.free;end;end;
 
//第一步function TCustomWinSocket.SendStream(AStream: TStream): Boolean;begin Result := False; if FSendStream = nil then begin FSendStream := AStream; Result := SendStreamPiece; end;end;//这步已经把流释放了function TCustomWinSocket.SendStreamPiece: Boolean;var Buffer: array[0..4095] of Byte; StartPos: Integer; AmountInBuf: Integer; AmountSent: Integer; ErrorCode: Integer; procedure DropStream; begin if FDropAfterSend then Disconnect(FSocket); FDropAfterSend := False; FSendStream.Free; FSendStream := nil; end;begin Lock; try Result := False; if FSendStream <> nil then begin if (FSocket = INVALID_SOCKET) or (not FConnected) then exit;//这句可能是个BUG 因为这样退出没有释放的流。 所以外面怎样判断是否已经释放了事隔问题 while True do begin StartPos := FSendStream.Position; AmountInBuf := FSendStream.Read(Buffer, SizeOf(Buffer)); if AmountInBuf > 0 then begin AmountSent := send(FSocket, Buffer, AmountInBuf, 0); if AmountSent = SOCKET_ERROR then begin ErrorCode := WSAGetLastError; if ErrorCode <> WSAEWOULDBLOCK then begin Error(Self, eeSend, ErrorCode); Disconnect(FSocket); DropStream; if FAsyncStyles <> [] then Abort; Break; end else begin FSendStream.Position := StartPos; Break; end; end else if AmountInBuf > AmountSent then FSendStream.Position := StartPos + AmountSent else if FSendStream.Position = FSendStream.Size then begin DropStream; //这里已经释放了! Break; end; end else begin DropStream; Break; end; end; Result := True; end; finally Unlock; end;end;// 结论 一般情况下, 你不用Sendstream.free; 但是遇到: if (FSocket = INVALID_SOCKET) or (not FConnected) then exit;//这句可能是个BUG 因为这样退出没有释放到流。 所以外面怎样判断是否已经释放了是个问题。
 
现在我发现是有很大问题,如果ClientSocket.socket.sendstream(myStream)后加上myStream.Free,程序会报错,如果不加的话,在测试时不停的发文件的话,内存使用直线上升,内存不但增大,大家应该很多人都遇到过才对啊,希望前辈们指点,怎么把myStream彻底的释放掉。
 
你可以看一下SendStream的代码,里面是不会帮你释放的,肯定是你要自己释放。至于程序报错,估计是其他代码出错了。
 
//请问 xianjun 这句不是释放了吗procedure DropStream; begin if FDropAfterSend then Disconnect(FSocket); FDropAfterSend := False; FSendStream.Free; FSendStream := nil; end;
 
if Assigned(yourstream) then freeandnil(yourstream);
 
看错代码了,看成是这个:function TBaseSocket.SendStream(AStream: TStream): Integer;从上面的代码可知,只SendStream返回True,那个Stream就是Free掉了,否则就自己Free。
 
测试了一下,确实是只SendStream=True时Free掉了,=False时需自己Free掉。大家以后也要注意此处,防止内存泄漏。
 
顶部