Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Сокеты. Ошибка при приеме картинки


Автор: Misha_White 19.5.2007, 09:28
Проблема непонятная, но может кто встречался с таким... Я уже не могу ниче понять...
Отправляю с клиента картинку каждые n сек... Первый раз принимается и отображается, а второй раз ругается при попытке загрузить Image из Стрима...
Сервер:
Код

procedure SendDisp;
Var Error:integer;
    DispSize:integer;
  //  DispStream:TMemoryStream;
begin
 DispStream:=TMemoryStream.Create;
 JpegIm.SaveToStream(DispStream);
 DispStream.Seek(0,soFromBeginning);
  DispSize:=DispStream.Size;
 if vSocket<>Socket_Error then
  begin
   Error:=Send(vSocket,DispSize,SizeOf(DispSize),0);
   
   Error:=Send(vSocket,DispStream.Memory^,DispSize,0);
   DispStream.Destroy;
   JpegIm.Destroy;
   if Error=Socket_Error then
    Begin
      ServerForm.Timer1.Enabled:=False;
     MessageDlg('Ошибка при передаче данных!',mtWarning,[mbOk],0);

    end;
  end
 else
  MessageDlg('Ошибка при передаче данных! Socket_Error',mtWarning,[mbOk],0);
end;


Клиент:
Код

procedure TClientForm.Socket_Proc_Read_Close(var Msg:TMessage);
Var err:integer;
    S:String;
begin
 if WSAGETSELECTEVENT(Msg.lParam) = FD_CLOSE then
  begin
   MessageDlg('Сервер закрыл соединение',mtInformation,[mbOk],0);
   ClientForm.Caption:='RemAdmin - Disconnected';
   ClientForm.Button1.Enabled:=true;
  end;

 if WSAGETSELECTEVENT(Msg.lParam) = FD_READ then
  begin
   if Reciv=false then
    begin
     Err:=recv(cSocket,DispSize,SizeOf(DispSize),0);
      If Err=Socket_Error then
        MessageBox(NULL,'Ошибка при получении!','Error',MB_OK)
      else
       begin
        reciv:=true;
         MyStream:=TMemoryStream.Create;
        JpegIm:=TJPEGImage.Create;
       end;
    end
   else
    begin
       SetLength(s,17520);
       err:= recv(cSocket,S[1],17520,0);
        If Err=Socket_Error then
         begin
          MessageBox(NULL,'Ошибка при получении!','Error',MB_OK);
          exit;
         end;
       MyStream.Write(S[1],err);
    if DispSize=MyStream.Size then
     begin
       MyStream.Position:=0; //Seek(0,soFromBeginning);
        JpegIm.LoadFromStream(MyStream);// Здесь ругаемся...
         Image1.Canvas.Draw(0,0,JpegIm);
        MyStream.Destroy;
        JpegIm.Destroy;
      Reciv:=false;
     end;
    end;
  end;

end;

Может поможет кто-нибудь
Запускал на двух разных машинах, там на третий раз ругается...

Автор: Misha_White 19.5.2007, 13:48
Обнаружил, что если ошибка появляется при третьем приеме, то ошибка возникает при попытке создать стрим...

Автор: MetalFan 19.5.2007, 14:49
по приведенным кускам кода можно сказать только то, что кривовато они написаны. всё.

Автор: Misha_White 20.5.2007, 05:26
MetalFan, 

Цитата(MetalFan @  19.5.2007,  21:49 Найти цитируемый пост)
кривовато они написаны

В каком месте?

Автор: MetalFan 20.5.2007, 11:22
Цитата(Misha_White @  19.5.2007,  09:28 Найти цитируемый пост)
Отправляю с клиента картинку каждые n сек...


Цитата(Misha_White @  19.5.2007,  09:28 Найти цитируемый пост)
Сервер:

так что откуда отправляется? сначало написано, что с клиента, а код отправки указан, как "сервер".

откуда вызывается Socket_Proc_Read_Close...
откуда уверенность, что вызовы будут происходить в ожидаемой последовательности...

+ почему бы не использовать какой-нибудь Client/ServerSocket ?

Автор: Misha_White 20.5.2007, 12:00
MetalFan, 
Все... smile  С сервера отправляю...

Цитата(MetalFan @  20.5.2007,  18:22 Найти цитируемый пост)
откуда вызывается Socket_Proc_Read_Close...

Код

procedure Socket_Proc_Read_Close(var Msg:TMessage);message NETEVENT_MSG;

Если на данном сокете начнется передача данных от клиента, в главное окно приложения поступит сообщение NETEVENT_MSG.
Это же сообщение поступит при разрыве соединения

Цитата(MetalFan @  20.5.2007,  18:22 Найти цитируемый пост)
почему бы не использовать какой-нибудь Client/ServerSocket ? 

  smile Я пишу курсовую по Сетям... Сеть нужно ручками описывать...

Автор: aktuba 20.5.2007, 14:48
Буквально недавно столкнулся с подобной проблемой. Три дня мучений ничего не дали. В итоге решил просто - поток создаю при создании формы и освобождаю при выгрузке формы...

Автор: Misha_White 20.5.2007, 16:08
aktuba, 
И что, работает?
А освобождаешь методом Free?

Автор: aktuba 21.5.2007, 08:24
Цитата

И что, работает?
А освобождаешь методом Free? 


Да, работает =))). Освобождаю при завершении программы чере Free =)

Автор: Misha_White 21.5.2007, 14:41
aktuba, 
И правда работает... Только чистить надо Clear-ом...

Автор: aktuba 21.5.2007, 16:01
Цитата

Только чистить надо Clear-ом... 


Так ты спрашивал как я освобождаю, а не чищу  smile 

Автор: Misha_White 22.5.2007, 02:24
aktuba, 
Ну я понял...
А че, Destroy не работает?

Автор: MetalFan 22.5.2007, 11:48
Цитата(Misha_White @  22.5.2007,  02:24 Найти цитируемый пост)
А че, Destroy не работает? 

а  это к чему?

Автор: aktuba 22.5.2007, 12:58
Цитата

А че, Destroy не работает?


А вот вопрос: зачем тебе Destroy, если для этого есть Free? Да и вообще - лучше FreeAndNil...

Автор: Misha_White 22.5.2007, 13:04
MetalFan, А это есть у TMemoryStream 2 метода Free и Destroy... А какой использовать?

Добавлено через 13 минут и 51 секунду
aktuba, 
Ну вот я и спрашиваю, что лучше использовать...

Автор: aktuba 22.5.2007, 16:54
Цитата

Ну вот я и спрашиваю, что лучше использовать... 


Я же сразу написал - FreeAndNil. Вот так:
Код

uses
  SysUtils;
...
FreeAndNil(lStream);

Автор: Misha_White 22.5.2007, 17:01
aktuba, 
Т.е. эта процедура наглухо валит стрим?

Автор: aktuba 23.5.2007, 02:01
Цитата

Т.е. эта процедура наглухо валит стрим? 


Эта процедура корректно убивает объект и обнуляет указатель на него.

Автор: Misha_White 24.5.2007, 12:48
aktuba, 
Спасибо, А чем Destroy не канает?

Автор: aktuba 25.5.2007, 01:15
Цитата

А чем Destroy не канает? 


Во-первых, Destroy не проверяет объект на наличие (на nil), что делает Free.
Во-вторых, ни Destroy, ни Free не присваивают указателю nil, что иногда бывает критично...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)