Question

  1. I use TIdTCPServer and TIdTCPClient, both client and server are on the same local network with 100 mbps
  2. Need to send files upto 2 MB each
  3. I have no experiences with Indy and Socket programming

*After the client send request to the server, it then looping until disconnect from the server, the file is created with the client itself but has 0 byte in size

IdTCPServer.OnExecute ...

begin
  CS.Enter;

  try
    InputString := AThread.Connection.ReadLn;

    if InputString = 'PIC' then begin
      AFullFileName := FFilePath + 'PIC01.jpg';
      if FileExists(AFullFileName) then begin
        AFileStream := TFileStream.Create(AFullFileName, fmOpenRead + fmShareDenyNone);

        AThread.Connection.OpenWriteBuffer;
        AThread.Connection.WriteStream(AFileStream);
        AThread.Connection.CloseWriteBuffer;

        FreeAndNil(AFileStream);
      end;

      AThread.Connection.Disconnect;
    end;
  except
    on E : Exception do
      ShowMessage(E.Message);
  end;

  CS.Leave;
end;

Client.OnButtonClick ...

begin
  with IdTCPClient do begin
    if Connected then Disconnect;
    Host := '127.0.0.1';
    Port := 2018;
    Connect;
    WriteLn('PIC');
    //different folder with server's folder
    if FileExists(FFilePath + 'PIC01.jpg') then
      DeleteFile(FFilePath + 'PIC01.jpg');
    AFileStream := TFileStream.Create(FFilePath + 'PIC01.jpg', fmCreate);
    while Connected do
      ReadStream(AFileStream, -1, true);
    FreeAndNil(AFileStream);
    Disconnect;
  end;
end;

Thanks all.

Était-ce utile?

La solution

You are making a classic newbie mistake of mismatching the WriteStream() and ReadStream() calls. By default, WriteStream() DOES NOT send the stream size, but the parameter values you are passing to ReadStream() tell it to expect the stream size.

Other mistakes you are making:

  1. You are calling ReadStream() in a loop, but not calling WriteStream() in a loop.

  2. Wrapping your entire OnExecute code in a critical section. Don't do that.

  3. Wrapping your entire OnExecute code in a try/except that swallows all exceptions. DO NOT swallow EIdException-derived exceptions. TIdTCPServer needs to handle them.

  4. Calling ShowMessage(). It is not thread-safe. Use Windows.MessageBox() instead.

  5. Using write buffering with WriteStream(). That is a huge waste of memory for large files. Get rid of that.

Update: try this:

Server:

begin
  InputString := AThread.Connection.ReadLn;
  if InputString = 'PIC' then begin
    AFullFileName := FFilePath + 'PIC01.jpg';
    AFileStream := TFileStream.Create(AFullFileName, fmOpenRead or fmShareDenyNone);
    try
      AThread.Connection.WriteStream(AFileStream, True, True);
    finally
      AFileStream.Free;
    end;
  end;
  AThread.Connection.Disconnect;
end;

Client:

begin
  if IdTCPClient.Connected then IdTCPClient.Disconnect;
  IdTCPClient.Host := '127.0.0.1';
  IdTCPClient.Port := 2018;
  if FileExists(FFilePath + 'PIC01.jpg') then
    DeleteFile(FFilePath + 'PIC01.jpg');
  AFileStream := TFileStream.Create(FFilePath + 'PIC01.jpg', fmCreate);
  try
    try
      IdTCPClient.Connect;
      try
        IdTCPClient.WriteLn('PIC');
        IdTCPClient.ReadStream(AFileStream, -1, False);
      finally
        IdTCPClient.Disconnect;
      end;
    finally
      AFileStream.Free;
    end;
  except
    DeleteFile(FFilePath + 'PIC01.jpg');
  end;
end;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top