Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Размер передаваемых данных через сокеты [D6, WinXP]


psa247 ©   (2006-10-06 17:34:00) 

Добрый день !
Проблема такая:
Есть клиент, есть сервер.
Через сокет сервера передаю с помощью MemoryStream XML-файл. При передаче
ServerForm.Server.Socket.Connections[0].SendStreamThenDrop(srcfile) - результат True

На клиентской стороне большие файлы полностью не приходят.

События:


procedure Send_File(Sock : TCustomWinSocket; testname : string);
var srcfile: TMemoryStream;
   fname : string;
   p : pointer;
   count, n : integer;
   buffer: array [0..MAX_BUF_SIZE] of Char;
begin
  fname:= Ini.ReadString('Tests',testname,'');
  if fname='' then begin
    Log('no such test '+ testname);
    Send_Reply(Sock, 'no such test '+ testname);
    exit;
    end;
  if not(FileExists(fname))then begin
    Log(fname +'- not exists');
    Send_Reply(Sock, fname +'- not exists');
    exit;
    end;
  try
    srcfile:= TMemoryStream.Create;
    srcfile.LoadFromFile(fname);
    count:= srcfile.size;
    Log('Send: '+fname+ ' to '+ Sock.RemoteHost);
    Log('filesize: '+ IntToStr(count) + ' byte');
    n:= 0;
    if ServerForm.Server.Socket.Connections[0].SendStreamThenDrop(srcfile)then Log(fname + ' - send successfully');

  except
    end;
end;


Клиент:

procedure TClientForm.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var str : widestring;
   tmp_Res : TPars_Res;
   count : integer;
   buffer: array [0..MAX_BUF_SIZE] of Char;
begin
  fStream.Position:= 0;
  repeat
    count:= Socket.ReceiveBuf(buffer,SizeOf(buffer));
    if count > 0 then fStream.Read(buffer,MAX_BUF_SIZE);
    str:= str + buffer;
    Log('Reseived ' +IntToStr(count)+ ' byte');
    MemoLog.Lines.Add(buffer);
  until(count <= 0);

    Log('Total: ' +IntToStr(fStream.Size)+ ' byte');
//   XMLDocument1.LoadFromStream(fStream);
//   fStream.SaveToFile('fill.fil');

...
  Client.Close;
end;


psa247   (2006-10-10 09:11:00) [1]

Благодарю за пояснение


Сергей М.   (2006-10-09 08:21:00) [2]


> смысл события Server.Accept


Accept есть факт подтверждения сервером запроса клиента на подключение с созданием соответствующей вирт.петли соединения с этим клиентом.


> дать понять, что он не Accept


Он ужеaccept.


> чтобы он разорвал соединение самостоятельно


.. ему нужно послать некое предопределенное инф.сообщение, по получению которого клиент в соответствии с этим сообщением обязан разорвать соединение.


psa247   (2006-10-08 16:42:00) [3]

Прошу пояснить смысл события Server.Accept и как клиенту дать понять, что он не Accept :), чтобы он разорвал соединение самостоятельно


medved_68   (2006-10-07 14:16:00) [4]

psa247Если уж на клиенте используешь сокетный поток, то почему бы не использовать WaitForDataдля ожидания доставки, а затем читать в буфер определенной длинныи сливать в отдельный поток данные из буфера именно столько сколько вернет процедура чтения из сокетного потока, например:
//Принимаем данные
           CapturePotok.Clear;
           repeat
             Readed:=FSocketPotok.Read(FReciveBuffer[0],8192);
             if Readed>0 then
                 CapturePotok.WriteBuffer(FReciveBuffer[0],Readed);

где FSocketPotokпоток связанный с сокетом, а CapturePotok- поток для принятых данных. Тогда выход из цикла чтения repeatбудет если until Readed<=0;:))))


Ketmar   (2006-10-06 18:44:00) [5]

для начала -- пояснить, что есть ClientRead() и откуда его зовут.


psa247   (2006-10-06 18:39:00) [6]


> Ketmar

Что ты предлагаешь ?


psa247   (2006-10-06 18:32:00) [7]

У меня асинхронные сокеты. Соответственно, ReceiveBuf возвратит значение, которое прочитал сервер, так ?


Ketmar   (2006-10-06 18:32:00) [8]

а мне вообще не ясно, зачем при подобном подходе использовать TCustomWinSocket. %-)


Ketmar   (2006-10-06 18:32:00) [9]

>[7] psa247(c) 6-Oct-2006, 18:32
>У меня асинхронные сокеты. Соответственно, ReceiveBuf
>возвратит значение, которое прочитал сервер, так ?
читаем [5] до полного просветления.


Verg   (2006-10-06 18:29:00) [10]

Кроме всего ..

Если пришел чистый FD_CLOSE (OnClose), то, тем не менее, необходимо "вычитать" все данные из соединения, если они там имеются
см. MSDN про WSAASyncSelect


Ketmar   (2006-10-06 18:20:00) [11]

ReceiveBuf only works in response to a read notification to a non-blocking windows socket. Blocking sockets must use a TWinSocketStream for reading.


psa247   (2006-10-06 18:08:00) [12]

Если правильно понял, то
ReceiveBuf(buffer,SizeOf(buffer)); возвращает количество полученных байт

?


Ketmar   (2006-10-06 18:04:00) [13]

так вот я тихо намекаю, что в вышеприведённом бреде никакими "count" и не пахнет...


psa247   (2006-10-06 18:03:00) [14]

Делаю по схеме:

получил определенное кол-во байт, записал в память, отобразил в лог для контроля, только там fstream.Read(buffer, count)


Ketmar   (2006-10-06 17:54:00) [15]

>[0] psa247(c) 6-Oct-2006, 17:34
>  if count > 0 then fStream.Read(buffer,MAX_BUF_SIZE);
это что за бред?

>  MemoLog.Lines.Add(buffer);
а это что за бред?


Наверх

Титульная страница Поиск, карта сайта Написать письмо