Модераторы: Snowy, Poseidon, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сокеты, Соединение TCP/IP 
:(
    Опции темы
Misha_White
Дата 15.5.2007, 01:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Цитата

Да, отправляем сначала размер стрима - 4 байта.


Почему именно 4 байта? Если Stream.Size=~64134, если это размер моего стрима, то почму нельзя указать его?

Цитата

А клиент сидит и ждёт, пока ему пришлют 4 байта.

Как этого добиться? smile 
У меня клиент в это время должен отправлять свои данные этому серверу... А если подрят вызывать Recv, то ерунда же получится...

CЕРВЕР
Код

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,DispSize,0);
       DispStream.Clear;
     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;
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);
     reciv:=true;
    end
   else
    begin
     JpegIm:=TJPEGImage.Create;
      MyStream:=TMemoryStream.Create;
       MyStream.SetSize(DispSize);
      MyStream.Position:=0;
     if DispSize<>0 then //DispSize=71123...
      err:= recv(cSocket,MyStream,DispSize,0); //В этом месте DispSize=-1!
       If Err=Socket_Error then
        MessageBox(NULL,'Ошибка при получении!','Error',MB_OK);
       MyStream.Position:=0;
        JpegIm.LoadFromStream(MyStream);
         Image1.Picture.Assign(JpegIm);
       MyStream.Destroy;
      JpegIm.Destroy;
     Reciv:=false;
    end;
   If Err=Socket_Error then
    MessageBox(NULL,'Ошибка при получении!','Error',MB_OK);
  end;

end;

Только не смейтесь пожалуйста, о сенсей! Как нужно сделать?

Это сообщение отредактировал(а) Misha_White - 15.5.2007, 02:20
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 15.5.2007, 12:55 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



уже лучше.

Цитата(Misha_White @  15.5.2007,  01:49 Найти цитируемый пост)
Почему именно 4 байта?
Потому что 4 байта - это до 2Гб данных.
Ты собираешься передавать данные большего размера?
Вряд ли... Да и 4 байта - основная еденица в 32-битных системах. С ней удобно работать.

Цитата(Misha_White @  15.5.2007,  01:49 Найти цитируемый пост)
У меня клиент в это время должен отправлять свои данные этому серверу... А если подрят вызывать Recv, то ерунда же получится...
Нет конечно. Нельзя вешаться.
Присасываться на приём нужно только по прибытии данных, иначе повиснешь наглухо.
Код
  ioctlsocket(SocketHandle, FIONREAD, size);
Этому коду скорми хэндл сокета и в size получишь кол-во данных в буфере сокета. Если 0, то читать нечего.

Цитата(Misha_White @  15.5.2007,  01:49 Найти цитируемый пост)
Error:=Send(vSocket,DispStream,DispSize,0);
Не компонент. Данные нужно передавать, и принимать соответственно. DispStream.Memory^, а не сам DispStream.
PM MAIL   Вверх
Misha_White
Дата 15.5.2007, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Цитата

Присасываться на приём нужно только по прибытии данных, иначе повиснешь наглухо.

А у меня процедурка TClientForm.Socket_Proc_Read_Close(var Msg:TMessage); вызывается только при прибытии данных или если поступило сообщение о закрытии сокета сервером!
Код

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

Т.е. сообщение NETEVENT_MSG; поступает от сервера только когда он передал данные, либо когда закрыл соединение...

Цитата(Snowy @  15.5.2007,  19:55 Найти цитируемый пост)
Цитата(Misha_White @  15.5.2007,  01:49 )
Error:=Send(vSocket,DispStream,DispSize,0);

Не компонент. Данные нужно передавать, и принимать соответственно. DispStream.Memory^, а не сам DispStream.

Т.е. нужно написать Send(vSocket,DispStream.Memory^,DispSize,0); и все начнет работать? А почему в Делфи у DispStream нету свойства(или метода) Memory? Т.е. DispStream.<Ctrl>+<Spase> ничего не дает? правда я не разыменовывал Memory и не компилировал... Но сейчас попробую...

Добавлено через 7 минут и 12 секунд
Snowy, 
 smile  Написал... Хоть кусок получил... Сказал, что Out of memory... Верхняя часть нормальная, а потом ужас... smile  Короче разноцветные полосы...

Это сообщение отредактировал(а) Misha_White - 15.5.2007, 16:06
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 15.5.2007, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Разумеется.
recv принимает только те данные, которые есть в буфере сокета.
Ты должен проверять - если принято меньше, чем указано байт, то нужно подождать, когда придут остальные данные и продолжить приём.
Это же не UDP - данные идут потоком, а не приходят за один раз.
Поэтому верх у тебя нормальный - он принялся.
А полосы ниже - мусор, вместо принятых данных.
Остальные данные должны были придти позже.
PM MAIL   Вверх
Misha_White
  Дата 15.5.2007, 16:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Спасибо! Завтра попробую... или сечас... уже поздно, надо спать... Т.е. получили кусок и вышли из процедуры?  Или заLOOPить прием стрима?

Это сообщение отредактировал(а) Misha_White - 15.5.2007, 16:37
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 15.5.2007, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Цитата(Misha_White @  15.5.2007,  16:36 Найти цитируемый пост)
Т.е. получили кусок и вышли из процедуры?  Или заLOOPить прием стрима?
Как хочешь.
Выбор стратегии за тобой.
PM MAIL   Вверх
Misha_White
Дата 15.5.2007, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
 smile Ok, ща попробуем...  smile Надо комп второй заводить
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Misha_White
  Дата 15.5.2007, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Код

if WSAGETSELECTEVENT(Msg.lParam) = FD_READ then
  begin
   if Reciv=false then
    begin
     Err:=recv(cSocket,DispSize,SizeOf(DispSize),0);
     reciv:=true;
    end
   else
    begin
     JpegIm:=TJPEGImage.Create;
      MyStream:=TMemoryStream.Create;
       MyStream.SetSize(DispSize);
      MyStream.Position:=0;
      StreamSize:=0;
     While DispSize<>StreamSize do
      begin
       err:= recv(cSocket,MyStream.Memory^,DispSize,0);
        StreamSize:=StreamSize+err;
        If Err=Socket_Error then
         begin
          MessageBox(NULL,'Ошибка при получении!','Error',MB_OK);
          Break;
         end;
      end;
       MyStream.Seek(0,soFromBeginning);
        JpegIm.LoadFromStream(MyStream); //Здесь ругается...
         Image1.Picture.Assign(JpegIm);
       MyStream.Destroy;
      JpegIm.Destroy;
     Reciv:=false;
    end;
   If Err=Socket_Error then
    MessageBox(NULL,'Ошибка при получении!','Error',MB_OK);
  end;


 smile Блин, уже голова не варит.... Помоги... Говорит, что ошибка с JPEG....
Не могу понять, то-ли я стрим не так принял или че... Ну размеры вроде совпадают... Вот думаю, может во время приема Seek-ать надо в конец полученного куска? Или все-таки с JPEG проблема?

Добавлено через 11 минут и 40 секунд
Snowy, 
Достал я тебя походу... Ладно, завтра буду разбираться с этим делом...

Это сообщение отредактировал(а) Misha_White - 15.5.2007, 17:53
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 15.5.2007, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Угу. Memory всегда указывает на начало стрима.
То есть ты постоянно перезаписываешь начало, а дальше не пишешь.
Заведи какой-нить буффер килобайта на 4, читай в него и скидывай в стрим, пока не накидаешь нужный размер.
В стрим скидывай через метод Write.
PM MAIL   Вверх
Misha_White
Дата 16.5.2007, 08:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Snowy, 
Че-т ничерта не пойму... А буфер какого типа брать? И как потом Write-ом кидать?  smile 
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 16.5.2007, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Любого. Например string отлично подходит.
Только сначала нужно ему длину определить SetLength(s, 4096);
А передавать recv и Write не сам стринг, а s[1]
PM MAIL   Вверх
Misha_White
Дата 16.5.2007, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Misha_White, 
Понятно, попробую... А во Write надо вторым параметром Count передавать... Это и будет 4096?

Добавлено через 4 минуты и 24 секунды
Snowy, 
Или Столько, сколько возвратит Recv?

Добавлено через 8 минут и 32 секунды
Код

 JpegIm:=TJPEGImage.Create;
      MyStream:=TMemoryStream.Create;
       MyStream.SetSize(DispSize);
      MyStream.Position:=0;
      StreamSize:=0;
        SetLength(s,4096);
     While DispSize<>StreamSize do
      begin
       err:= recv(cSocket,S[1],DispSize,0);
        StreamSize:=StreamSize+err;
         MyStream.Write(S[1],err);

        If Err=Socket_Error then
         begin
          MessageBox(NULL,'Ошибка при получении!','Error',MB_OK);
          Break;
         end;
      end;
       MyStream.Seek(0,soFromBeginning);
        JpegIm.LoadFromStream(MyStream);
         Image1.Picture.Assign(JpegIm);
       MyStream.Destroy;
           JpegIm.Destroy;
     Reciv:=false;

Че-то не так.... smile

Добавлено через 11 минут и 6 секунд
 smile 
--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 16.5.2007, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Цитата(Misha_White @  16.5.2007,  10:25 Найти цитируемый пост)
MyStream.SetSize(DispSize);

Цитата(Misha_White @  16.5.2007,  10:25 Найти цитируемый пост)
StreamSize:=StreamSize+err;

Убери установку размера стрима.
Он сам растянется по мере записи в него.

PM MAIL   Вверх
Misha_White
Дата 16.5.2007, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 25.4.2007
Где: Кодинск

Репутация: нет
Всего: 1



Цитата(Snowy @  16.5.2007,  17:46 Найти цитируемый пост)
StreamSize:=StreamSize+err;

это - размер принятого... Чтобы сравнить с DispSize...

Цитата(Misha_White @  16.5.2007,  17:25 Найти цитируемый пост)
err:= recv(cSocket,S[1],DispSize,0);
        StreamSize:=StreamSize+err;
         MyStream.Write(S[1],err);

Во Write что писать? Err или 4096?



--------------------
Я не волшебник... я только учусь...  
PM MAIL ICQ Skype   Вверх
Snowy
Дата 16.5.2007, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Цитата(Misha_White @  16.5.2007,  11:13 Найти цитируемый пост)
это - размер принятого... Чтобы сравнить с DispSize...
А зачем? У стрима уже есть Size.

Цитата(Misha_White @  16.5.2007,  11:13 Найти цитируемый пост)
Во Write что писать? Err или 4096?
err
PM MAIL   Вверх
Страницы: (5) Все 1 2 [3] 4 5 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0610 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.