从客户端向服务器发送图片的问题

时间:2010-07-17 16:36:53

标签: delphi sockets filestream

我正在尝试使用服务器和客户端套接字将图片从'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方法而创建? 请帮忙!我做错了什么?

2 个答案:

答案 0 :(得分:1)

我不知道出了什么问题,但我会尝试解决一个更简单的问题。你甚至可以转移一些简单的东西吗?看看你是否可以传输只包含“Hello”的c:\ hello.txt并让它以正确的顺序到达。检查流和结果文件应该更容易,看看是否/哪里出现乱码。如果您在服务器上没有收到“Hello”,那么您知道它与数据的大小或复杂性无关。

答案 1 :(得分:1)

尽管名称如此,但SendStream()并不保证发送整个流(特别是如果您使用的是非阻塞套接字)。它的返回值返回实际发送的字节数。如果在一次调用中发送的流量小于整个流量,则必须再次调用SendStream(),可能需要多次,以完成发送整个流(SendText()也存在相同的问题)。

另一方面,ReceiveLength()仅报告套接字上有多少字节可用。这可能小于发送的完整流(同样,ReceiveText()可能不会收到完整发送的字符串,因为它在内部使用ReceiveLength()。

发送流(或一般任意数据)的最佳方法是先发送数据大小,然后再发送实际数据。继续调用SendBuf / Stream / Text()直到达到该大小(如果非阻塞套接字返回-1而不引发异常,则必须等待套接字的OnWrite事件在套接字再次接受更多数据之前触发)。在接收端,首先读取大小,然后继续读取,直到达到指定的大小。在获得所有数据之前,您可能必须多次触发OnRead事件。

转到http://www.deja.comhttp://forums.embarcadero.com搜索Borland / CodeGear / Embarcadero新闻组/论坛档案。我以前多次发布过示例代码。

相关问题