Форум: "Сети";
Текущий архив: 2004.11.28;
Скачать: [xml.tar.bz2];
ВнизПередача 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;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.033 c