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

Вниз

SendText   Найти похожие ветки 

 
DNT   (2002-09-15 10:27) [0]

Есть небольшая проблемка.

Необходимо несколько раз использовать Socket.SendText, но так, что-бы все пришло не вместе а раздельно.
Как это реализовать?
Спасибо.


 
Алексей Ким   (2002-09-15 11:38) [1]

clientsocket1.socket.sendtext("tvoi text|chtotoochendlinnoeinerazumnoe|eshe raz tvoi text")?
или делай на приемнике и на передатчике запоминание длинны того что ты пишешь типа "|size=10|abcdeabcde" или "#chegototam dgsfsdf"
и по # определяй что тебе надо, а на сервере парсь строки


 
DNT   (2002-09-15 12:14) [2]

А по другому нельзя?

Т.е. я пишу код
Socket.SendText (text);
...
код
...
Socket.sendtext (nick);

Там, где "код" может можно что-то вставить, что бы socket отправил уже накопившеюся информацию?


 
Алексей Ким   (2002-09-15 12:16) [3]

хм... а он тебе и отправляет то что ты пишешь в сендтекст для
наглядности попробуй сделать sleep(5000); и проверь что ты получаешь на серваке


 
DNT   (2002-09-15 12:41) [4]

Поставил sleep(60), работает нормально.
С sleep(10) тоже вроде работает, но помоему это не выход.
Sleep(1) уже работает, но не всегда, поэтому сомнения появляются и для sleep (10) & sleep (60).


 
Алексей Ким   (2002-09-15 12:56) [5]

хм.. у меня есть подозрение что сокет просто не успевает понять что передача окончена а считает это за тормоза инета


 
VID   (2002-09-15 13:16) [6]

to dnt: а нак кой, извращаться ? не лучше ли, на сервере принимать такой "склееный" пакет, и разбивать его на отдельные логические части на основе МЕТОК ОКОНЧАНИЯ ПАКЕТА ? Т.е. так как показал Алексей КИМ ?

Просто я это к тому, что возможно на твоём компе Sleep(60) возможно и представляте необходимую задержку, для того, что бы пакеты пришли порознь, но не факт что на другом компе эта задержка будет достаточной.


 
Ketmar   (2002-09-15 13:29) [7]

я уже говорил, что TCP - протокол ПОТОКОВЫЙ. а поток нет смысла делить на пакеты - их там просто нет. так что - только разбирать "склееные" пакеты. иначе - глюквище.

Satanas Nobiscum! 15-Sep-XXXVII A.S.


 
Алексей Ким   (2002-09-15 14:14) [8]

2vid>в моем методе есть 2 подкола:
1)например у тебя разделитель !@# а у юзверя вдруг пришла мысль
послать !@# сервак получает белиберду и дохнет
2)выходит из первого что надо сделать разделитель подлинее - больше траффика особенно в таких штуках как чаты и подобные вещи
поэтому нада ивращатся


 
DNT   (2002-09-15 14:49) [9]

Вот поэтому и ищу другой способ решения проблемы, а не разделителями.


 
ElectHp   (2002-09-15 14:53) [10]

Алексей Ким
если пользователь посылает !@# тогда прога это пределит и пошлет две, три, четыре... Собаки. как это делается в Делфи со стрингом если хочешь написать " то пишешь "" чтоб он не сочел это за конец строки.


 
Алексей Ким   (2002-09-15 15:12) [11]

electhp это увеличивает траффик а еси тебе так хочется меня
подкалывать то посмотри мой последний пост повнимательней


 
VID   (2002-09-15 18:43) [12]

Вот сложный но стабильный вариант:

USES B64{алгоритм шифрования строк - необходим для того, что бы в выходящей строке не было ни одного НЕПЕЧАТНОГО символа}

Const PE = #13; //Метка окончания посылаемой строки SENDTEXT
//Обязательно должно быть #13

//Реализуем отправку текста

Function B64_Encrypt(S:String):String;
begin
{}
end;

function B64Decrypt(S:String):String;
begin
{}
end;

Function CreatePacket(Text1, Text2:String):String;
Var ST:TStringList;
begin
ST:=TStringList.Create;
ST.Add(B64_Encrypt(Text1));
ST.Add(b64_ecrypt(text2));
Result := ST.CommaText + PE;
ST.Free;
end;

Procedure SendPacket(Packet:String);
begin
client.Socket.SendText(Packet);
end;

Procedure Form1.Btn1click(..);
Var A,B:String;
begin
A:="Hello ";
B:="Server!";
SendPacket(CreatePacket(A,B));
end;

//Теперь реализуем приём текста

Function GetPacketList(Source:String; TargetList:TStrings):Integer;
Var I:Integer;
begin
TargetList.Clear;
IF Source = "" then Exit;
TargetList.Text := Source;
TargetList.ADD(PE);
I:=TargetList.Count;
REPEAT
Dec(I);
IF TargetList[I]<>PE then TargetList.Insert(I, PE);
UNTIL I<=1;
Result := TargetList.Count;
end;

Procedure ServerClientRead(...);
VAR ST:TStringList;
begin
ST:=TStringList.Create;
GetPacketList(Socket.ReceivedText, ST);

//На данный момент в списке ST находится текст от клиента, причём каждая строка представляет собой отдельный "отклееный" текст от клиента.

С каждой строкой списка ST надо обращаться так:
LST:=TStringList.Create;
LST.CommaText := B64_Decrypt(ST[0]); //Т.к. каждый пакет шёл в виде CommaText, то на приёмнике, необходимо вновь преобразовать пакет в список строк, что и сделано.

Иными словами в списке LST будет:
LST[1] = "Hello ";
LST[2] = "Server!";
//Что и требовалось получить

ST.FREE;LST.FREE;
end;


Не спорю что предложенный мною метод перемудрён, и возможно его концепция стабильности слишком "навороченная" для поставленной перед автором сабжа задачи, но зато этот метод работает БЕЗ ОШИБОК.
Во всяком случае, я в своём чате использую такой стандарт передачи/приёма текста.


 
Malder   (2002-09-15 18:50) [13]

DNT, никак не реализовать. Пользуйся разделителями. И уверяю тебя - во всех популярных программах так и сделано. Не изобретай велосипед.


 
VID   (2002-09-15 20:08) [14]

вот так всегда :)
Мой пример, имеет некоторую недоработку, здесь я продолжать не буду - если кого-то заинтересовало пишите на vidsnap@mail.ru


 
Malder   (2002-09-15 20:10) [15]

VID, вау. Зачем такой гемморой ?

Объясняю популярно. В заголовке пакета должен стоять размер пакета (не считая заголовка).

Посылаешь "<РАЗМЕР ПАКЕТА>ДАННЫЕ"

Соответственно, при приеме ты должен обнаружить между "<>" размер ПОСЛЕДУЮЩЕГО текста. И считать этот пакет.
Дальше опять считывать размер пакета.

Пример.

Посылается "<13>Привет, мир !"

Сначала считываешь размер заголовка между "<>". Получаешь 13. Следующие 13 символов считаешь телом пакета.

Допустим, хитрый пользователь решает обмануть программу.

И он посылает строку: "<234<>ГА ГА >ГА ВИСНИ"

В результате посылается пакет: "<21><234<>ГА ГА >ГА ВИСНИ"

Но. При приеме никакой ошибки нету. Считывается размер пакета = 21. Потом все последующие 21 символ считаются телом пакета независимо от содержания.
Подставой может быть то, что на удаленной стороне стоит не твоя программа, а другая, которая будет намеренно обманывать твою. Например, она может подделать заголовок пакета и твоя программа начнет глючить.

Еще тонкости. Не стоит отбрасывать всю последующую информацию после заголовка и тела пакета. TCP может склеивать пакеты.
То есть, ты отсылаешь "Привет, мир !" а потом "Пока, мир !", но до получателя сразу дойдет "Привет, мир !Пока, мир !". Или в нашем случае: "<13>Привет, мир !<11>Пока, мир !". Так что не нужно игнорировать последующий текст.

Обратная ситуация, пакеты будут разбиты.

Допустим приходит такой пакет: "<13>Приве"
Во первых, нужно контролировать, что длина всего пакета вместе с заголовком 9 байт. Поэтому обработав 4 байта заголовка, где сказано, что тело пакета состоит за 13 байтов, не надо тут же обрабатывать и их. Нужно дождаться, когда придут недостающие 8 байтов (символов).

Может придти такая строка "<13" - для таких ситуация как раз и нужны разделители "<>". Сначала нужно дождаться окончания передачи заголовка пакета, потом уж принять сам пакет.

Конечно, реализация всех этих требований требует дополнительных усилий, но несоблюдение этих правил практически гарантирует крах вашей программы при эксплуатации


 
Алексей Ким   (2002-09-15 22:43) [16]

в общем толчемся на одном месте последний пост-повторение моево
(15.09.02 11:38) но он самый разумный :)


 
VID   (2002-09-16 01:17) [17]

TO Malder: согласен, гемморой...

Если у тебя есть код, реализующий алгоритм парсинга строк по твоему методу, может выложишь здесь ?
А то писать, уже задолбало, на одну и туже тему...
Хотя, конечно, напишу есть понадобится...


 
@NetMan   (2002-09-16 08:36) [18]

А чем вас не устраивает способ отправки файла из ФАКа (конечно надо хотя бы кое где try except вставить и если збой-обламывать клиента и восстанавливать сервак)


 
Алексей Ким   (2002-09-16 08:48) [19]

2@NetMan>читай внимательно
2VID>А что за не доработки в твоем методе?


 
jonik pegas   (2002-09-16 11:15) [20]

Посылай пакеты по UDP-тогда они не будут обьединятся. Правда это потребует программирования на WinApi. Неплохо написано на тему сабжа в книжке ""Эффективное программирование TCP/IP" изд. "Питер"


 
Malder   (2002-09-16 12:00) [21]

jonik pegas, доброе утро. UDP не гарантирует доставки пакета, тебе самому придется делать проверки, а это еще сложнее. И вообще, почему для UDP нужно использовать WinApi ? С тем же успехом можно сказать, что и для TCP нужно использовать WinApi.
Есть же компоненты TNMUDP и TClientSocket&TServerSocket соответственно.

И еще. Нужно самому немного поразбираться и попрактиковаться в сабже, а потом другим советовать...


 
VID   (2002-09-16 19:22) [22]

TO Алексей КИМ: Если хочешь, я тебе на почту пришлю рабочий алгоритм... там и постараюсь подробно всё расписать


 
s002156Shurik   (2002-09-17 12:00) [23]

Малдер хитрый чел я тоже так делаю.
одну тонкость хочу посоветовать может он ей тоже и пользуется незнаю.
Тонкость на случай прихода неполного пакета. Я использую буферную строку, в которую на событие прихода сабса добавляю пришедший отрезок строки, и вызываю функцию вырезки готового сообщения. Эта функция отрезает по методу Молдера <11>Привет Мир!
столько сколько ей надо из начала строки и выдает true. А если сабс не полный не отрезает и выдает false.
тем временем пакеты приходят дополняя буферную строку и вызывая ту самую отрезающую кусочки функцию. вот и вся тонкость.
Удачи.!


 
Алексей Ким   (2002-09-17 15:01) [24]

2VID>шли


 
VID   (2002-09-17 19:55) [25]

to Алексей КИМ: отправил на указанный тобою в анкете почт. адрес


 
Алексей Ким   (2002-09-17 20:10) [26]

2VID получил щас/завтра буду разбиратся



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

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

Наверх





Память: 0.52 MB
Время: 0.008 c
3-45691
alexts
2002-10-25 14:21
2002.11.14
Проблема MS SQL 2000 и OLE


14-46123
NetBreaker666
2002-10-19 02:55
2002.11.14
Динамическое создание объекта TWebBrowser


1-45948
@Ujin
2002-11-04 12:08
2002.11.14
Создание


14-46105
blackman
2002-10-22 23:10
2002.11.14
Кто и сколько времени пишет программы на DELPHI ?


1-45886
Брат
2002-11-05 17:04
2002.11.14
Как остановить выполнение программы на определенный промежуток...





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский