Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.03.25;
Скачать: CL | DM;

Вниз

Размер передаваемых данных через сокеты   Найти похожие ветки 

 
psa247 ©   (2006-10-06 17:34) [0]

Добрый день !
Проблема такая:
Есть клиент, есть сервер.
Через сокет сервера передаю с помощью 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;


 
Ketmar ©   (2006-10-06 17:54) [1]

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

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


 
psa247 ©   (2006-10-06 18:03) [2]

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

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


 
Ketmar ©   (2006-10-06 18:04) [3]

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


 
psa247 ©   (2006-10-06 18:08) [4]

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

?


 
Ketmar ©   (2006-10-06 18:20) [5]

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


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

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

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


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

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


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

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


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

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


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


> Ketmar

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


 
Ketmar ©   (2006-10-06 18:44) [11]

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


 
medved_68 ©   (2006-10-07 14:16) [12]

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; :))))


 
psa247 ©   (2006-10-08 16:42) [13]

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


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


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


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


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


Он уже accept.


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


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


 
psa247 ©   (2006-10-10 09:11) [15]

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



Страницы: 1 вся ветка

Текущий архив: 2007.03.25;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.029 c
2-1172855293
pasha star
2007-03-02 20:08
2007.03.25
Мигание как в mIRC


15-1172441059
Ломброзо
2007-02-26 01:04
2007.03.25
Философское


15-1172952909
Prede
2007-03-03 23:15
2007.03.25
Macintosh


15-1171568690
Johnmen
2007-02-15 22:44
2007.03.25
Что Вам мешает купить Windows?


2-1173088934
Клара
2007-03-05 13:02
2007.03.25
Выпадающий список