Главная страница
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.028 c
11-1151927465
oleg_l_k
2006-07-03 15:51
2007.03.25
handle моего приложения


15-1172722039
Константинов
2007-03-01 07:07
2007.03.25
Сегодня 1-ый день на новом месте. Что меня ждет – не знаю…


2-1172739333
iviom
2007-03-01 11:55
2007.03.25
DBComboBox


6-1160476510
Zorro666
2006-10-10 14:35
2007.03.25
реализация сетевого протокола поверх tcp соединения


15-1172809796
Tugodum
2007-03-02 07:29
2007.03.25
Где найти помошь от Delphi7