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

Вниз

Передача Stream в Socket ах   Найти похожие ветки 

 
seregin2   (2004-09-22 08:25) [0]

Здравствуйте!
Я загружаю файл в TMemoryStream, затем пишу его в socket - Socket.SendStream(MemStream). Сервер-сокет принимает его, но размер принятых данных получается больше. Я смотрел что там получается - файл передается кусками по 8192 байта (XP и 2000) (в том числе последний). Ладно, ерунда, последний я обрезаю. Но идут еще несколько кусков. Каждый кусок тоже извращен - идет какое-то количество правильных байтов, потом около 2 килобайтов нулей #0, продолжается файл до границы куска (типа "Hello, wo"#0#0#0#"rld!"). Положение "дыры" каждый раз изменяется.

Если передавать файлы меньше 8 килобайт, то все ОК. Можно конечно извратиться и не писать в сокет поток, но тогда тайна останется нераскрытой :) В чем проблема?

Кстати дома под XP - все замечательно. Версии Делфей одинаковые.
И еще отличие XP от 2000 - пишу в сокет сначала строку, потом поток - в ХР сначала приходит строка, потом поток (отдельными кусками). В 2000 - к строке прилепляется поток, все это режется по 8 кило и отсылается. Но это лирика, вопрос был выше.


 
seregin2   (2004-09-22 08:27) [1]

Соврал - поучается так:

n-й кусок:
Hello, wo#0#0#0#0
n+1-й кусок:
rld!#0#0#0#0#0#0


 
atruhin ©   (2004-09-22 08:41) [2]

Приведи код как принимаешь данные.


 
seregin2   (2004-09-22 08:44) [3]


procedure TForm1.srvClientRead(Sender: TObject; Socket: TCustomWinSocket);
var s: array[0..50000] of Char;
   z: array[0..20] of char;
   x: Integer;
begin
 x:= Socket.ReceiveLength;
 Socket.ReceiveBuf(s, x);
 if not Receiving then begin
   StrCopy(z, s);
   DataSize:= StrToInt(z);
   Receiving:= true;
   msin:= TMemoryStream.Create;
   msin.Write(s[StrLen(z)+1], x-StrLen(z)-1);
   DataSize:= DataSize - (x-StrLen(z)-1);
 end
 else begin
   if DataSize>x then
     msin.Write(s, x)
   else
     msin.Write(s, DataSize);
   DataSize:= DataSize - x;
 end;
 if DataSize<=0 then begin
   msin.Position:= 0;
   msin.SaveToFile("c:\to.dat");
   msin.Free;
 end;
end;


 
seregin2   (2004-09-22 08:45) [4]

сначала я пишу в сокет 0-строку с длиной потока (как в одном из примеров в форуме сто лет назад)


 
atruhin ©   (2004-09-22 09:35) [5]

Во первых Socket.ReceiveBuf(s, x) это функция и она возвращает кол-во принатых байт. Ты это значение не используешь.
Во вторых StrCopy(z, s) работает с нуль терминированными строками а с чего у тебя будет в конце буфера #0.
C   if not Receiving then begin вообще непонятная логика.
Здесь была куча примеров пересылки файлов через сокеты. Посмотри.


 
seregin2   (2004-09-22 09:58) [6]

спасибо, сейчас проверю. StrCopy работает. я строку нарочно завершаю нулем. If not Receiving - это для отделения первого куска от последующих.


 
seregin2   (2004-09-22 10:04) [7]

Спасибо большое. Очень стыдно признавать, что все это можно было прочитать в справке.
А в Xp ReceiveLength возращала не estimate длину данных, а точную - мне повезло.


 
atruhin ©   (2004-09-22 10:23) [8]

>>я строку нарочно завершаю нулем.
Причем тут передаваемая строка речь идет о принятом буфере.
>>If not Receiving - это для отделения первого куска от >>последующих.
В потоковых данных нет и не может быть кусков. Т.е. любую переданную тобой строку система может разделить на любое кол-во кусков, или объеденить.



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

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

Наверх




Память: 0.48 MB
Время: 0.041 c
1-1100200566
xkiller
2004-11-11 22:16
2004.11.28
В exe-файле несколько разных иконок


1-1100534916
ceval
2004-11-15 19:08
2004.11.28
Подскажите как в диалоге задать путь к


14-1100149608
Dmitriy O.
2004-11-11 08:06
2004.11.28
Ясир Арафат умер. Официально


1-1100256549
TSa
2004-11-12 13:49
2004.11.28
Спрятать приложение в панали задач


4-1097648493
Woolen
2004-10-13 10:21
2004.11.28
Как загрузить файл exe в память полностью?