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

Вниз

ClientSocket, ServerSocket - несколько отправок   Найти похожие ветки 

 
Brand   (2002-07-11 23:07) [0]

Если один из этих компонентов выполняет SendText и тут в момент выполнения опять вызывается SendText. Что будет: выскочет ошибка или этот запрос станет в очередь и выполнится после того, как выполнится предыдущая SendText?


 
[nex]   (2002-07-12 00:55) [1]

Ошибка не вылятитъ, но текст из первой отправки может слится с текстом из следующей. Устранить этот баг можно только одним способом: надо вначале строки указать её длину, чтобы при получении инфы считывалось только нужная длина и удаляешь её, а следующий текст идёт на следующий обработчик...


 
Digitman   (2002-07-12 08:15) [2]

>Brand
Запросы на передачу и прием становятся в очередь.

>[nex]
Это не баг. Это - особенность штатного SOCK_STREAM-режима работы гнезд.


 
Brand   (2002-07-12 13:56) [3]

Я попробовал написать два раза подряд:
Socket.SendText(.....);
Socket.SendText(.....);
На сервере, и вправду, все принялось, как одна строка. А как-же сделать, чтобы это было все-таки две отдельных отправки?


 
Digitman   (2002-07-12 14:09) [4]

никак.
откажись от компонентов, использующих поточный протокол и используй иные компоненты для работы в режиме UDP.

или реализуй логику, предложенную [nex]



 
Brand   (2002-07-12 20:44) [5]

Например?


 
Digitman   (2002-07-15 08:17) [6]

>Brand

Чего "например" ?


 
Alex SV   (2002-07-17 10:41) [7]

Удалено модератором


 
Digitman   (2002-07-17 11:42) [8]

>Alex SV

Тебе есть что сказать по делу, сударь ? Есть - говори, нет - вперед в "Потрепаться" !

По СУТИ поставленного вопроса ("как-же сделать, чтобы это было все-таки две отдельных отправки") я вижу единственное решение - использование message-oriented режима TCP/IP-протокола. О деталях и ограничениях альтернативы речи пока не шло.
У тебя иное мнение ? Есть возражения ? Что ж , излагай ... чего трепаться-то бестолку ?


 
Alex SV   (2002-07-17 15:59) [9]

Видеть единственное решение это очень серьезное заболевание. Надо расширять кругозор, товарищ!
Что-бы добраться из пункта А в пункт В всегда есть множество путей.

Source.ru рекомендует использовать метод SendStream ClientSocket1.Socket.SendStream(srcfile). Отличным решением данной задачи является тот же файловый поток - TFileStream (либо поток в памяти - TMemoryStream). Принимать частички данных из сокета можно через событие OnRead (OnClientRead), используя универсальный метод ReceiveBuf. Определить размер полученного блока можно методом ReceiveLength. Также можно воспользоваться сокетным потоком.
Книга "Delphi 5. Руководство для профессионалов" (это не про Вас, Цифра-Мужик) предлагает использовать команды типа "#N", "#U", "#M", и т.д., которые вводятся самим разработчиком просто чтобы определить, что прислали из сокета.
На странице Королевство Delphi есть описание способа обмена информацией межу сервером и клиентом при котором сервер подтверждает получение информации и после этого клиент высылает следующую посылку.
Вот так. Учите мат-часть.
А послать в "Потрепаться" может любой дурак.


 
Digitman   (2002-07-17 17:05) [10]

Слушай, любезный, ты читать умеешь вопрос ?

Цитирую персонально для тебя, "товарищ с широким кругозором" :

>>как-же сделать, чтобы это было все-таки две отдельных отправки

Никаких "отдельных отправок" режим SOCK_STREAM никогда не обеспечит. И не надо "лепить" сюда деление исходящего/входящего потока на логические дейтаграммы - это из другой оперы, и автор про твою "другую оперу" ни слова не произнес.



 
Alex SV   (2002-07-17 17:15) [11]

Если деление, в данном случае, принесет наилучший результат - его можно и нужно использовать!
А оперу надо брать такую, которая максимально ефективно решит вопрос. Ну это же всем понятно... хотя нет, видно не всем.


 
Digitman   (2002-07-17 17:28) [12]

>Alex SV

Вот ты возьми да автору объясни, что вопрос им поставлен некорректно !!!!!
Чего ты мне тут хочешь доказать ?? Я и без тебя прекрасно ориентируюсь в логике реализации машины состояния приемника при работе с поточным протоколом !!!! :|


 
Alex SV   (2002-07-17 17:33) [13]

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


 
Digitman   (2002-07-17 17:46) [14]

Это вот ты так автору "предлагаешь пути к решению " ? ))

см. Alex SV (17.07.02 10:41)

Да ты даже окружения задачи не выяснил ! Как можно иметь смелость предлагать нечто альтернативное, не зная окружения проблемы ? Я уже 3-й день веду автора к моменту, когда он сам "созреет" расписать подробно это самое окружение ! И - пусть даже с помощью наводящих вопросов ! Кои тебя столь сильно задевают ! Ты же просто - встрял и понес околесицу ! Возьми да и взвали на себя тяжелейшую задачу "раскрутки" вопроса : нужно ли это автору, знает ли он, может ли он, хочет ли он вникнуть во все тонкости и принять самостоятельное решение об альтернативной технологии и программной логике !


 
Alex SV   (2002-07-17 18:05) [15]

см. Alex SV (17.07.02 10:41)
Это я не предлагал автору путь к решению (только слепой мог не заметить).
Это я порекомендовал ему обратить внимание на собеседника(Digitman), который уже неоднократно в форуме указывает задающим вопрос на их неподготовленность и уходит не предложив ничего конкретного.

Конечно, если вести автора через болото - то 3 дня это еще не финиш. Бедный автор, если он идет за таким Сусаниным.
Попробуй по прямой дороге - и просто и надежно. Хотя есть один минус - никто не увидет твоей надутой важности и не услышыт твоих навороченных терминов, которые, я уверен, ты сам, где-то слышал, но точно не помниш что они означают.

Я считаю, что надо быть попроще и люди к тебе потянутся.
Причем заметь - меня ничто не задевает, по крайней мере я не ставлю по четыре знака восклицания в конце своих фраз.
А знаеш почему? Потому что человек, когда говорит дело - он спокоен. А если человек говорит то, в чем сомневается - тогда конечно нервозность, много восклицательных знаков и т.д.
У меня есть телефон хорошего психиатра. Дать?


 
Digitman   (2002-07-17 18:18) [16]

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


 
Alex SV   (2002-07-17 18:33) [17]

Я уже высказывал свое мнение:
Alex SV (17.07.02 15:59)
У меня есть работающие примеры.
На сегодняшний день лучшего решения я не придумал.
Но,... еще не вечер.


 
Digitman   (2002-07-17 18:43) [18]

>Alex SV
см. (17.07.02 15:59)

>>Определить размер полученного блока можно методом ReceiveLength

Неверно. Совершенно неверно.
Читай хэлп и проверяй многократно, прежде чем "советовать"

Returns the number of bytes ready to be sent over the socket connection.

function ReceiveLength: Integer;

Description

Call ReceiveLength to determine the amount of information to read over the socket connection in response to an asynchronous read notification.

Note: ReceiveLength is not guaranteed to be accurate for streaming socket connections.

Где ты здесь видишь хоть какое-либо упоминание , что буфер приемника уже ПОЛУЧИЛ фрагмент потока размером в ReceiveLength ?


 
Digitman   (2002-07-17 18:44) [19]

bytes ready to be sent !!!!!


 
anatol   (2002-07-17 18:50) [20]

Privet! a ya predlagaiu brosit" ClientSocket i ServerSocket i ispolzovat" Indy. Tam tacoi problemi ne voznicaet. Da i o4eni mnogo veshei cotorie v ClientSocket + ServerSocket prihoditsea pisat" rukami metri koda zdes" uje relizovano.


 
Digitman   (2002-07-17 18:58) [21]

>anatol

С чего ты взял, что это - проблема ? И где гарантия надежной работы кода под нашумевшей вывеской "Indy" ? В момент, когда Борланд писал BSS, Indy как отдельный продукт (в какой-то там альфа- или бэта-версии) уже существовал и был известен Борланду, однако Борланд-таки использовал уже реализованные им, собственные cтандартные сетевые компоненты ... и был прав - они действительно выверены многократно .. хотя и нет в них "супернавороченных" методов для беззаботного транспорта парой строчек кода всего, чего только душа не пожелает ...)


 
anatol   (2002-07-17 19:12) [22]

Digitman ©:
Horosho ato ne problema :) prosto v indy v smisle raboti economit mnogo vremeni da i coli4estvo oshibok voznicaiushie ot "crivih ruk" umenshaetsea.

No vidno dlea vas ato delo printsipa :).
A componenti Indy destvitel"no o4en" horoshaya vesh". Mi isplol"zovali ih v dovol"no criti4nih proiectah i vse rabotalo otli4no.
A nas4et pri4inah borlanda: naverno ne nam sudit".


 
Digitman   (2002-07-18 08:18) [23]

>anatol

Не буду возражать. Нравится Indy - пожалуйста, используй.
Повторю только избитую истину : лучшее - враг хорошего.


 
Alex SV   (2002-07-18 10:16) [24]

Удалено модератором


 
Digitman   (2002-07-18 10:42) [25]

>Alex SV

Сударь, ты - хам.

И, думаю, ничего сколь-либо серьезного из себя не представляешь как специалист. К сожалению, ты сам сделал это очевидным, не представив контраргументы по изложенному в постинге от (17.07.02 18:43).

На сем закончим диалог.
Извини уж, но - без уважения.


 
Alex SV   (2002-07-18 10:49) [26]

Действительно, никогда в жизни еще не общался с таким неучем.
Чего ты сюда приходиш, мистер - лючше пойди да книжку почитай.
Начни сначала с простеньких...


 
cyborg   (2002-07-18 22:41) [27]

Alex SV зря ты на цифрового наезжаешь, он умные вещи говорит, хотя некоторым не нравится, мы тут с ним то же спорили дня 2 или 3 по этому же поводу и пришёл я к выводу что так как я делал не правильно, верней правильно да примитивно и ошибки не обрабатывало, в итоге у муня теперь не всё, но почти всё чики пуки работает, сделал себе свой протокол обмена с возможным будущим расширением, правда возможные оборванные куски у меня он не склеивает, а просто игнорирует. Ты посмотри чего он наделал, в потрепаться есть тема одна про проекты. Вижу зарегистрился ты, да инфы что-тот жиденько у тебя.


 
panov   (2002-07-19 07:14) [28]

>Alex SV © (18.07.02 10:49)
Если тебе больше нечего делать, кроме как оскорблять и коверкать ники, бездоказательными постингами пытаясь поставить себя на один уровень с признанными авторитетами, то тебе прямая дорога в "Потрепаться"
Здесь твои постинги будут удаляться.


 
Alex SV   (2002-07-19 10:29) [29]

Удалено модератором


 
Alibaba   (2002-07-19 10:37) [30]

Удалено модератором


 
panov   (2002-07-19 11:21) [31]

>Alex SV © (19.07.02 10:29)
>Alibaba © (19.07.02 10:37

Треплются в форуме "Потрепаться"


 
Fredericco   (2002-07-19 16:45) [32]

2Brand
Я делаю так.
Есть масив и переменная

Mas:array[1..100] of string;
CurrentM:integer;

Когда я хочу отправить текст я просто делаю так

CurrentM:=CurrentM+1;
Mas[CurrentM]:=YourText;

Есть так же таймер с интервалом в 50 миллисекунд, каждый раз когда он срабатывает выполняется такой код:

if CurrentM<1 then Exit;
ClientSocket1.Socket.SendtText(Mas[1]);
for i:=2 to CurrentM do
Mas[i-1]:=Mas[i];
CurrentM:=CurrentM-1;

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


 
Alibaba   (2002-07-19 16:57) [33]

Да, это тоже может работать, но..
Почему 50 миллисекунд?
Сетка может очень тормозить и указанного времени не хватит для отправки - в результате опять все склеится.


 
Fredericco   (2002-07-19 17:25) [34]

2Alibaba ©
Из-за чего сетка будет тормозить то?!
50 миллисекунд вполне приемлемо, по крайней мере у меня нормально работает.


 
Alibaba   (2002-07-19 17:40) [35]

У нас на работе иногда сетка притормаживает по разным причинам:
1. С одного компа на другой качают жирный кусок информации.
2. Перестраивают сетку, меняют конфигурацию.

И тогда наблюдаются заметные задержки при работе с сетью.
Можно говорить о том что сетка администрится не правильно и настроенна не очень хорошо - только мне от этого не легче.


 
Fredericco   (2002-07-19 18:35) [36]

2Alibaba
Но я же не посылаю сообщение каждые 50 миллисекунд, а лишь проверяю, если есть сообщение в очереди я его пошлю, а если нет то и не буду ничего посылать

> if CurrentM<1 then Exit;



 
cyborg   (2002-07-20 08:28) [37]

Значит так, как нужно сделать правильно, без задержек и прочего ненужного бреда.

Выдумываем структуру передачи данный в которой обязательно должен быть признак правильности данных, т.е. получатель будет опозноватьь данные что это те данные которые нужны, т.е. правильные.Сразу после него должна быть длина следующих за ним данных.
Назовём например признак данных именем Check, длинну DataSize.
Теперь по этим данным у нас будет в начало каждого сообщения входить эти данные.

Const
Check : Cardinal = $ABABAB01;//Признак начала получаемых данных
Var
DataSize : Cardinal; //Размер данных


При каждом посылании данных мы будем включать в начало каждого сообщения эти данные. Например нужно посылать строку StringMessage


Var
StringMessage : AnsiString;
HeadData : Array[1..8] of char;//Заголовок
...

StringMessage:="Привет!";
DataSize:=Length(StringMessage);
Move(Check,HeadData[1],4);
Move(DataSize,HeadData[5],4);
StringMessage:=HeadData[1]+HeadData[2]+HeadData[3]+HeadData[4]+
HeadData[5]+HeadData[6]+HeadData[7]+HeadData[8]+
StringMessage;
//Нужно отдельно складывать потому что если встретится в массиве
//#0 то он обрежется
Socket.SendText(StringMessage);//Отсылаем

теперь получаем строку

Var
StringReceive : AnsiString;
ReceiveCheck : Cardinal;
Quit : Boolean;
...
Quit:=False;
StringReceive:=Socket.ReceiveText;
repeat
Move(StringReceive[1],ReceiveCheck,4);
Move(StringReceive[5],DataSize,4);
if ReceiveCheck=Check then //Если признак начала правильный
if DataSize+8<=Length StringReceive then
begin //Если сообщение не обрезанное
SetLength(StringMessage,DataSize);
Move(StringReceive[9],StringMessage[1],DataSize);
Delete(StringReceive,1,DataSize+8);
Тут выводим строку StringMessage в окно или обрабатываем её
end
else Quit:=True
else Quit:=True;
until quit;


Вот простой способ разделения строк, единственное он не склеивает разорванные строки.
Писал код в браузере в Дельфи не проверял, возможны некоторые ошибки.


 
Fredericco   (2002-07-22 10:53) [38]

2cyborg ©
Давай относительно не нужного бреда будем помягче.
Может для кого-то это не бред и нужный.
В моем случае исключена возможность "склееных" сообщений. В твоем же идет проверка, что дает клиенту возможность однозначно прочитать только свое сообщение.
Минусы моего способа низкая скорость.
Минусы твоего способа "склеенное" сообщение получит только один клиент, второй ничего не получит.
ИМХО для разных задач разный способ.


 
panov   (2002-07-22 13:45) [39]

Если передается текстовая информация, достаточно к каждой строке добавить символ(символы)-разделители, и при обработке принятой информации просто вычленять строки, что делается достаточно просто...


 
cyborg   (2002-07-22 14:53) [40]

Какой один, какой другой клиент?
В один сокет приходит, в одном и разделяется всё. И все сообщения получаются, а не только первое. Этот код хоть 100 склееных сообщений разделит.


 
cyborg   (2002-07-22 14:55) [41]

panov © про разделители в строке мы тут обсуждали уже, работать будет, но всё таки .... короче обсуждали уже :)


 
Fredericco   (2002-07-22 16:39) [42]

2cyborg ©
У тебя только один клиент?
У меня нет. И важно что бы каждый получил таки свое сообщение.
А на счет разделителя в строке, мой собственный протокол построен так, что клиент только свое и заберет.
У меня структура системы такая, чот один клиент посылает серверу комманду: пошли клиенту такому-то такое-то сообщение. И если в тоже мнгновение получится: пошли клиенту другому-то такое-то сообщение. То сообщение придет первому и сдвоенное. Вот почему я использую алгоритм описанный мной выше.

> ИМХО для разных задач разный способ.



 
Fredericco   (2002-07-22 16:51) [43]

Так. Я не прав. Думал только о клиентах. То что я придумал - можно проще, так как вы советуете. Сорри, что спорил.
Встает вопрос.
Скажем есть на сервере единая процедура обработки сообщения пришедшего от клиентов.
procedure TextReceiveFromClient(const Text:string);
Вот сервер получил сдвоенное сообщение, разделил его на два, как дальше поступить? Ведь нужно сначал вызвать процедуру с первым сообщением, а потом со вторым? Как быть?


 
cyborg   (2002-07-22 17:08) [44]

Делается так:
Procedure ProcessData( передаваемые данные; var Socket : TWinSocket);
Begin
//обрабатываем данные если нужно посылаем Socket что требуется
End;


дальше из моего примера

repeat
Move(StringReceive[1],ReceiveCheck,4);
Move(StringReceive[5],DataSize,4);
if ReceiveCheck=Check then //Если признак начала правильный
if DataSize+8<=Length StringReceive then
begin //Если сообщение не обрезанное
SetLength(StringMessage,DataSize);
Move(StringReceive[9],StringMessage[1],DataSize);
Delete(StringReceive,1,DataSize+8);
ProcessData( StringMessage, Socket);
end
else Quit:=True
else Quit:=True;
until quit;


 
Brand   (2002-07-22 17:35) [45]

А вот и я, автор.
Блин, я уже давно все сделал и забыл про эту тему. А вот зашел, шляжу, а тут такое..................
Граждане, спокойствие, только спокойствие.


 
Fredericco   (2002-07-22 19:09) [46]

cyborg ©
Может я ошибаюсь и сейчас (конец рабочего дня - простительно), но на стороне сервера ИМХО, прием данных делать как ты сказал, а отправку по моему способу. Тогда и клиентское сообщение не потеряется на сервере (твой способ) и каждому клиенту дойдет его сообщение (мой способ).
Ежели что не так, критекуй!


 
cyborg   (2002-07-22 20:03) [47]

С этим кодом работает как сервер так и клиент, сокет то в принцпе такой же, только сервер ждёт когда к нему подключатся, а клиент подключается, у меня чат работает по такому принципу, что сервер, что клиенты, каждая мессага идёт в свою трубу, никакие сокеты между собой по идее не смешиваются, когда сервер посылает одному клиенту, это сообщение никак не может придти в непредназначенный сокет. Если бы так было, как ты говоришь, то при отправке из сервера мессаг всем клиентам, то все вместе мессаги приходили бы только первому попавшемуся клиенту?
Я понимаю так, что при подключении клиента к серверу сервер создает новый сокет и никак данные из одного сокета не могут попасть в другой сокет, если только сам сервер не посылает им данные.
Лучше конечно сделать с sendbuf но в строке удобно то, что можно легко обратиться к определённому байту string[x] поэтому я так сделал, в принципе sendbuf и sendtext одно и тоже, sendtext использует тот же SendBuf, сам в исходниках посмотри. Ctrl держи и мышкой на функции нажимай, если у тебя пути прописаны к библиотекам модулей, то перескочишь на исходный текст той функции.


 
Fredericco   (2002-07-23 10:38) [48]

2cyborg ©
Ты прав. У меня просто не совсем стандартное пременнение сокетов, и структура сети, моей, тоже спецефичная, поэтому такие идеи и рождались.


 
Alibaba   (2002-07-25 11:09) [49]

> Brand
Ты ж акуратненько с такими вопросами... :)


 
Alex SV   (2002-07-25 11:11) [50]

> Brand
Так расскажи нам как ты реализовал отправку?


 
Володя Шарапов   (2002-07-25 11:15) [51]

Я тут почитал как предлагают организовать пересылку.
Попробовал с использованием разделительных символов - у меня получилось.



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

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

Наверх




Память: 0.59 MB
Время: 0.009 c
7-85720
maxim2
2002-07-17 14:35
2002.09.26
Можноли программно эмулировать прокрутку колесика мыши?


14-85669
AL2002
2002-08-30 22:33
2002.09.26
Есть в И-нете коллекции MOD, S3M, IT, XM и MIDI музыки?


3-85354
Kalinka
2002-09-04 13:58
2002.09.26
Как реализовать такой запрос


1-85466
Gari
2002-09-16 09:08
2002.09.26
Работа с компонентами


14-85650
RV
2002-08-29 11:30
2002.09.26
кому нечего делать.





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