2013-06-01 6 views
0
  1. я использую TIdTCPServer и TIdTCPClient, как клиент и сервер находятся на одной и той же локальной сети с 100 Мбит
  2. нужно отправить файлы до 2 Мб каждый
  3. У меня нет опыта с Инди и гнездо программирования

* После того, как запрос клиента отправить на сервер, он затем цикл до отключения от сервера, файл создается с самим клиентом, но имеет 0 байт размеромНужна помощь отправки файла с Инди

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; 

Спасибо всем.

ответ

4

Вы делаете классическую ошибку новичка, несовпадающую с вызовами WriteStream() и ReadStream(). По умолчанию WriteStream() НЕ отправляет размер потока, но значения параметров, которые вы передаете в ReadStream(), сообщают ему, что он ожидает размер потока.

Других ошибок вы делаете:

  1. Вы звоните ReadStream() в цикле, но не вызывая WriteStream() в цикле.

  2. Обертывание всего кода OnExecute в критическом разделе. Не делай этого.

  3. Обертывание всего кода OnExecute в попытке/кроме того, что проглатываются все исключения. НЕ проглатывайте исключения, полученные из EIdException. TIdTCPServer должен обрабатывать их.

  4. Вызов ShowMessage(). Он не является потокобезопасным. Вместо этого используйте Windows.MessageBox().

  5. Использование буферизации записи с помощью WriteStream(). Это огромная трата памяти для больших файлов. Избавься от этого.

Update: попробуйте это:

Сервер:

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; 

Клиент:

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; 
+0

Больше вопросов, я на самом деле начал копируя пример кода Инди, в соответствии с вашими советы, когда ReadStream() должен быть в цикле ??? – Artisan

+0

Мне не нужен критический раздел ???, что это на самом деле? :( – Artisan

+0

Все методы внутри OnExecute должны быть потокобезопасными справа ?, включая доступ к VCL. – Artisan

 Смежные вопросы

  • Нет связанных вопросов^_^