我正在尝试使用服务器和客户端套接字将图片从'C:\ picture.bmp'发送到'c:\ temp \ picture.bmp' 客户端onconnect事件处理程序如下:
procedure TForm2.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
var
fs : tfilestream;
begin
fs := TFileStream.create('C:\picture.bmp', fmOpenRead);//picture allready exists
socket.SendStream(fs);
fs.free;
end;
和服务器onclientread为:
procedure TForm2.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
fmm : tfilestream;
iLen: Integer;
Bfr: Pointer;
begin
iLen := Socket.ReceiveLength;
GetMem(Bfr, iLen);
fmm := TFileStream.Create('c:\temp\picture.bmp', fmCreate or
fmShareDenyWrite);
try
Socket.ReceiveBuf(Bfr^, iLen);
fmm.Write(Bfr^, iLen);
finally
FreeMem(Bfr);
fmm.Free;
end;
end;
图片已收到/已创建,但是从未收到过损坏,即因为tfilestream.create方法而创建? 请帮忙!我做错了什么?
答案 0 :(得分:1)
我不知道出了什么问题,但我会尝试解决一个更简单的问题。你甚至可以转移一些简单的东西吗?看看你是否可以传输只包含“Hello”的c:\ hello.txt并让它以正确的顺序到达。检查流和结果文件应该更容易,看看是否/哪里出现乱码。如果您在服务器上没有收到“Hello”,那么您知道它与数据的大小或复杂性无关。
答案 1 :(得分:1)
尽管名称如此,但SendStream()并不保证发送整个流(特别是如果您使用的是非阻塞套接字)。它的返回值返回实际发送的字节数。如果在一次调用中发送的流量小于整个流量,则必须再次调用SendStream(),可能需要多次,以完成发送整个流(SendText()也存在相同的问题)。
另一方面,ReceiveLength()仅报告套接字上有多少字节可用。这可能小于发送的完整流(同样,ReceiveText()可能不会收到完整发送的字符串,因为它在内部使用ReceiveLength()。
发送流(或一般任意数据)的最佳方法是先发送数据大小,然后再发送实际数据。继续调用SendBuf / Stream / Text()直到达到该大小(如果非阻塞套接字返回-1而不引发异常,则必须等待套接字的OnWrite事件在套接字再次接受更多数据之前触发)。在接收端,首先读取大小,然后继续读取,直到达到指定的大小。在获得所有数据之前,您可能必须多次触发OnRead事件。
转到http://www.deja.com和http://forums.embarcadero.com搜索Borland / CodeGear / Embarcadero新闻组/论坛档案。我以前多次发布过示例代码。