Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2008.10.12;
Скачать: [xml.tar.bz2];

Вниз

Не пойму где ошибка(сокеты)...   Найти похожие ветки 

 
Sergl   (2007-11-01 10:05) [0]

Передаю файл через сокеты.
На сервере:

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
 Socket: TCustomWinSocket);
var ms:tmemorystream;
begin
if serversocket1.Socket.Connections[0].ReceiveText="get_file" then begin
  showmessage("file------");
  ms:= TMemoryStream.Create;
  try
    // Получаем данные на передачу.
    ms.LoadFromFile(PChar(maskedit1.Text));
    ms.Position:= 0;
    // Добавляем длину данных, чтобы клиент знал, сколько данных будет передано
    // Добавляем #0 , чтобы можно было определить, где заканчивается информация о размере.
    Socket.SendText(IntToStr(ms.Size) + #0);
    // Посылаем его.
    Socket.SendStream(ms);
    socket.SendText("#end_file#");
  except
    // Итак, осталось освободить поток, если что-то не так.
    ms.Free;
 end;
end;
end;


на кленте:

procedure TForm1.ClientSocket1Read(Sender: TObject;
 Socket: TCustomWinSocket);
 var s, sl: string;
     prov:bool;
begin
s:= Socket.ReceiveText;
// Если мы не в режиме приёма:
if not Reciving then
begin
  // Теперь нам необходимо получить длину потока данных.
  SetLength(sl, StrLen(PChar(s))+1); // +1 for the null terminator
  StrLCopy(@sl[1], PChar(s), Length(sl)-1);
  DataSize:= StrToInt(sl);
  Data:= TMemoryStream.Create;
  // Удаляем информацию о размере из данных.
  Delete(s, 1, Length(sl));
  Reciving:= true;
end;
// Сохраняем данные в файл, до тех пор, пока не получим все данные.
if copy(s,length(s)-9,10)="#end_file#" then begin
//  showmessage("Ура");
 prov:=true;
//  Delete(s,length(s)-9,10);
end;
if s<>"#end_file#" then prov:=false;
try
if prov=false then Data.Write(s[1], length(s));

if prov=true then begin
  if Data.Size = DataSize then
  begin
    Data.Position:= 0;
    data.SaveToFile("c:\000.jpg");
    Data.Free;
    Reciving:= false;
//     Socket.Close;
    showmessage("Файл принят");
  end else showmessage("Файл принят не удачно");
 end;
except
  Data.Free;
end;
end;


Данные клиент получает, но не читает что ему пришло "#end_file#". Почему?


 
Сергей М. ©   (2007-11-01 10:43) [1]


> не читает что ему пришло "#end_file#". Почему?


Потому что "#end_file#" ему не пришло.


 
Sergl   (2007-11-01 10:46) [2]

Как сделать что-бы ему это пришло?


 
Slym ©   (2007-11-01 10:59) [3]

// Итак, осталось освободить поток, если что-то не так - не нужно
На лицо работа с неблокирующими сокетами в блокирующей манере... непалучедся :)


 
Sergl   (2007-11-01 11:04) [4]


> На лицо работа с неблокирующими сокетами в блокирующей манере.
> .. непалучедся

Подкинте пожалуйста литературу(ссылок) про работа с блокированием и не блокированием.


 
Slym ©   (2007-11-01 11:04) [5]

Sergl   (01.11.07 10:05)
Данные клиент получает, но не читает что ему пришло "#end_file#". Почему?

Объясняю:
Socket.SendStream(ms); - послал только одну "пачку" данных до возникновения WOULBLOCK и вышел
socket.SendText("#end_file#");
посылаешь маркер конца файла, но файл фактически не отправлен... т.к. оставшиеся "пачки" Stream досылаются по мере освобождения отправляющего буфера


 
Slym ©   (2007-11-01 11:08) [6]

Sergl   (01.11.07 11:04) [4]
Подкинте пожалуйста литературу(ссылок) про работа с блокированием и не блокированием.

http://delphimaster.net/view/6-1192377094/


 
Sergl   (2007-11-01 11:10) [7]

Вместо socket.sendtext("#end_file#") дописать к ms, перед тем как отправить вот это ms.read("#end_file#",10);

Так пойдет?


 
Slym ©   (2007-11-01 11:13) [8]

Sergl   (01.11.07 11:10) [7]
Так пойдет?

Ходьбой это не назавешь... Похромает...


 
Sergl   (2007-11-01 11:21) [9]

Не хочет дописывать... ms.read("#end_file#",10);
Как дописать?


 
Slym ©   (2007-11-01 11:22) [10]

Sergl   (01.11.07 11:21) [9]
Write :)


 
Сергей М. ©   (2007-11-01 11:23) [11]


> Не хочет дописывать


А где ты дописываешь ? Нигде)
read по-буржуйски - это читать, а не писать)


 
Sergl   (2007-11-01 11:24) [12]


> Write :)

Извеняюсь за тупость:)
Однако #end_file# так и не находит...


 
Сергей М. ©   (2007-11-01 11:49) [13]


> DataSize:= StrToInt(sl);


С чего ты взял, что в sl находится строка, содержащая ожидаемок число, и ничего более кроме этого числа ?


 
Slym ©   (2007-11-01 12:55) [14]

Sergl   (01.11.07 11:24) [12]
за тупость:)

Для особотупых повторяю: http://delphimaster.net/view/6-1192377094/


 
Sergl ©   (2007-11-01 12:57) [15]


> Для особотупых повторяю

Попрошу без хамства... За ссылку спасибо.


 
Sergl ©   (2007-11-01 13:04) [16]


> С чего ты взял, что в sl находится строка, содержащая ожидаемок
> число, и ничего более кроме этого числа ?

Я с сервера, перед отправкой файла, передаю вот это     Socket.SendText(IntToStr(ms.Size) + #0);
Я так думаю что клиент следующим сообщением получает ms.Size


 
Sergl ©   (2007-11-01 13:20) [17]

Как, всетаки, дописать к моему потоку, перед отправкой, #end_file#.
Так ms.write(#end_file#,10)  - что то не работает


 
Sergl ©   (2007-11-01 13:22) [18]

Ковычки забыл) - ms.write("#end_file#",10);


 
Сергей М. ©   (2007-11-01 13:38) [19]


> клиент следующим сообщением получает ms.Size
>


Может получить, а может и не получить.

TCP - протокол поточный, а не месседж-ориентированный, в нем нет разбиения на сообщения, данные передаются сплошным потоком.


 
Sergl ©   (2007-11-01 13:45) [20]

Данные передаются партиями(я так понимаю), и что бы при передачи размера небыло лишнего сзади я ставлю #0. А чтобы небыло лишнего спереди я могу отсылать что-то вроде #start_file#


 
Sergl ©   (2007-11-01 13:51) [21]

Как, всетаки, дописать к моему потоку, перед отправкой, #end_file#.
Так ms.write(#end_file#,10)  - что то не работает


 
Сергей М. ©   (2007-11-01 13:57) [22]


> Данные передаются партиями(я так понимаю)


Неправильно понимаешь.

Данные передаются потоком.


 
Slym ©   (2007-11-02 06:07) [23]

Sergl ©   (01.11.07 12:57) [15]
Попрошу без хамства...

Че ты уперся в ms.write(#end_file#,10)? как ... на новые ворота... :)
ms.write(PChar("#end_file#")^,10);

Sergl ©   (01.11.07 13:45) [20]
Данные передаются партиями(я так понимаю)

неправильно понимаешь...
протокол поточный: т.е. один Send на другой стороне может разбится на несколько Recv и на оборот несколько Send могут слипнуться вызвав один Recv
Отправив 10 "посылок" по Nбайт  получатель получит
от 1 "посылки" (размером N*10байт) до N*10 "посылок" (размером 1байт) причем каждый раз разного количества и размера :)


 
Prostoy_paren   (2007-11-06 12:57) [24]

>Slym ©  
Короче говоря тебе прийдется проверять сохранять все что тебе пришло в заранее подготовленном буфере(TMemoryStream подойдет)!
Потом анализировать на нахождение нуля #0 в твоем буфере.
Затем разбирать свой начало файла(его размер) и конец.
Тебе выше объясняли, что TCP может прислать от 1 и до MaxBuf байт.(MaxBuf=8192 байт - хотя это тоже можно настроить! :) ).
И вопрос нахрена тебе конец файла если ты посылаеш его длину?
И зачем посылать текстовую длину файла, если можно заполнить структуру скажем:
TFileRec=Record
 FileStart:String[10];
 FileSize :Cardinal;
...
End;

И проверять на наличие определенного(постоянного) размера данных в буфере приема?
А то работа со строками это всегда гемор (по моему мнению)


 
Prostoy_paren   (2007-11-06 13:26) [25]

Т.е.

...
Data.Write(S,Length(s));
if not Reciving then
begin
 // Теперь нам необходимо получить длину потока данных.
 SetLength(s, Data.Size); // +1 for the null terminator
 Data.Position:=0;
 Data.Read(s[1],Data.Size);
 _Size:=strlen(S)+1;
 StrLCopy(@sl[1], PChar(s), _Size);
 DataSize:= StrToInt(sl);
 Data:= TMemoryStream.Create;//это перенести в глобальный блок
 //здесь учесть что Data уже не пуст
 // Удаляем информацию о размере из данных.
 Delete(s, 1, Length(sl));
 Reciving:= true;
end;



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

Форум: "Сети";
Текущий архив: 2008.10.12;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.08 c
15-1219126004
vajo
2008-08-19 10:06
2008.10.12
Подскажите с драйвером?


3-1208021181
koss__
2008-04-12 21:26
2008.10.12
Out Of Memory в датасете


15-1219235641
sD
2008-08-20 16:34
2008.10.12
динамическое создание форм


15-1219647892
rx275d7_jedi
2008-08-25 11:04
2008.10.12
Написать программу


2-1220338927
sD
2008-09-02 11:02
2008.10.12
Изменение FormStyle при создании формы





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский