Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

TCPClient вторая посылка не проходит


Страницы:   1 2

novichek ©   (2010-05-11 22:29:00) 

клиент:

 if TcpClient1.Connected then TcpClient1.Sendln(edit2.Text);

сервер:

procedure TForm1.TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient);
begin
 edit1.Text:= ClientSocket.Receiveln;
end;

первая отправка строки доходит до сервера, последующте нет, хотя connected клиента True.

добавил:

    TcpClient1.Sendln(edit2.Text);
    TcpClient1.Disconnect;
    TcpClient1.Connect;

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

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


Вариант   (2010-05-13 06:42:00) [1]


> novichek   (12.05.10 22:50) [25]


> и второй вопрос насчет хоста.
> если у меня на компе 3 айпи адреса, при иницилизации сервера
> я не указываю ему TcpServer.LocalHost а только назначаю
> порт. он где будет слушать порт?


На всех адресах


Вариант   (2010-05-13 06:20:00) [2]


> novichek   (12.05.10 22:50) [25]

По моему мнению ( смотрим RFC 896  часть The solution to the small-packet problem) для локаоной сети это не так важно-
> "With our scheme, every character the user  types  will
> find  TCP with an idle connection, and the character will
> be sent
> at once, just as in the no-control case.  The user  will
>  see  no
> visible  delay.   Thus,  our  scheme  performs as well as
> the no-
> control scheme and provides better responsiveness than the
>  timer
> scheme."
- где под
> With our scheme
-  подразумевался алгоритм Nagle. Кратко об английском тексте - Можешь включить, можешь выключить, время отклика сети маленькое и пакеты будут отправляться быстро, практически одинаково что для схемы с алгоритмом, что для схемы без без него.
А лучший критерий - практика и свой собственный опыт. Проведи эксперимент и если заметишь разницу - выбери более подходящее для тебя вариант.


novichek   (2010-05-12 22:50:00) [3]

спасибо большое за разъяснения, картина почти вырисовалась!

осталось только уточнить, пакеты мелкие, около 10 байт, но летать будут часто по обычной внутренней сетке.

так и не понял, стоит ли включать этот алгоритм Nagla или нет?

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


Вариант   (2010-05-12 14:16:00) [4]

var
b:bool;
d:DWORD;
i:integer;
begin
 b:=true;// Выключасет алгоритм Nagla, а false включает
 I:=setsockopt(SocketHandle, IPPROTO_TCP, TCP_NODELAY,@b,  sizeof(bool));
 if i <> 0 then
 begin
   d:=WsaGetLastError;
 //  как-то реагируем на ошибку
 end;
end;


novichek   (2010-05-12 13:58:00) [5]

простите, так правильно ? :

var
 b: byte;
..
 b:= 0;
 setsockopt(TTCPClient(Sender).Handle, IPPROTO_IP, TCP_NODELAY, pointer(b),  1)


Вариант   (2010-05-12 13:09:00) [6]


> Сергей М. ©   (12.05.10 12:03) [21]

Задержка есть, но это не грабли.

В RFC 896 дается примерная прикидка, насколько будет большой такая задержка - фактически это время движения пакета до удаленного хоста +подтверждение пакета удаленным хостом, если есть неподтвержденные пакеты.  Если таковых пакетов нет, то задержка 0. При работе в интернете, при сильной загрузке сети много мелких пакетов могут так же иметь задержку в доставке из-за перегрузки канала и даже большую. При больших пакетах, имеющих размер больше окна передачи буферизация  произойдет независимо от того, включен алгоритм или нет. Поэтому я склонен при работе в интернете по крайней мере придерживаться рекомендаций, в том числе и из MSDN

> Application writers should not set TCP_NODELAY unless the
> impact of doing so is well-understood and desired because
> setting TCP_NODELAY can have a significant negative impact
> on network and application performance

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


Сергей М.   (2010-05-12 12:03:00) [7]


> Вариант   (12.05.10 06:44) [17]


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


Сергей М.   (2010-05-12 11:59:00) [8]


> тогда если клиент будет ждать прием а нужно будет что-то
> опять отправить.


На то есть метод WaitForData()


> как-то всё заумно сделано


Нормально сделано.


Вариант   (2010-05-12 09:02:00) [9]


> novichek   (11.05.10 23:31) [4]



> setsockopt(TTCPClient(Sender).Handle, IPPROTO_IP, TCP_NODELAY,
>   0,  1)

И еще раз возвращаясь - код неверный, ибо выделенное жирыным должно быть не  значением, а указателем


Вариант   (2010-05-12 07:10:00) [10]


> novichek   (11.05.10 23:31) [4]


> setsockopt(TTCPClient(Sender).Handle, IPPROTO_IP, TCP_NODELAY,
>  0,  1)

Это кстати включает алгоритм Nagla - по умолчанию он и так включен


Вариант   (2010-05-12 06:44:00) [11]


> Сергей М. ©   (11.05.10 23:55) [10]


> Как только ты разнесешь своих клиента и сервера по разным
> углам Тырнета, грабли со включенным алгоритмом Нагля обязательно
> хлобыстнут)

А какие грабли? Насколько я читал , алгоритм Nagla как раз предназначен для решения проблем по "углам тырнета", для оптимизации нагрузки сети, в том числе для решения проблем "малых" пакетов.


Германн   (2010-05-12 01:41:00) [12]


> как-то всё заумно сделано..

Дозволено ли мне будет скромно предложить обратить внимание на ICS
http://www.overbyte.be/frame_index.html
?


novichek   (2010-05-12 01:04:00) [13]

наверное нужно на клиенте так же вешать TcpClient1.Receiveln..
но тогда если клиент будет ждать прием а нужно будет что-то опять отправить..

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


Сергей М.   (2010-05-12 00:18:00) [14]


> можео как-то это отменить


А зачем ? Так задумано разработчиком.


> странно что клиент показывает connected - true и пытается
> посылать не вызывая исключения


Оно и не должно возникакть - на то есть событие OnError


> в обработчике TcpServer1Accept можно ли на цикл повесить


Именно так.


> с отправкой от сервера клиенту ничего не получается


Значит у тебя ошибка.


Сергей М.   (2010-05-12 00:14:00) [15]

> в том то и дело что не разрывает.

Разрывает, даже не сомневайся.

> следующие событие TcpServer1Accept не приходит

А с какого перепугу оно должно возникнуть повторно, если клиент законнектился всего один раз ?


novichek   (2010-05-12 00:09:00) [16]

ой да, после завершения TcpServer1Accept разрывает коннект сервер..
а можео как-то это отменить?
и странно что клиент показывает connected - true и пытается посылать не вызывая исключения..

или в обработчике TcpServer1Accept можно ли на цикл повесить Receiveln, тем самым не давая оборвать соединение и ждать очередных данных? правильно ли это будет?

ну и так же с отправкой от сервера клиенту ничего не получается..


novichek   (2010-05-11 23:55:00) [17]

Сергей М., так в том то и дело что не разрывает..
наверное из-за того что не всё вычитаваю, следующие событие TcpServer1Accept не приходит


Сергей М.   (2010-05-11 23:55:00) [18]


> стало теперь принимать и ..без setsockopt.


Как только ты разнесешь своих клиента и сервера по разным углам Тырнета, грабли со включенным алгоритмом Нагля обязательно хлобыстнут)


novichek   (2010-05-11 23:54:00) [19]

не подскажите как теперь передать от серверка данные клиенту..

пробую так:

procedure TForm1.Button1Click(Sender: TObject);
begin
 TcpServer1.Sendln(timeToStr(time));
end;

procedure TForm1.TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient);
var
 s: String;
begin

 s:= ClientSocket.Receiveln;
 while s<>'' do begin
   edit1.Text:= edit1.Text + s;
   s:= ClientSocket.Receiveln;
 end;

 ClientSocket.Sendln(timeToStr(time));

end;

у клиента обрабатываю

procedure TForm1.TcpClient1Receive(Sender: TObject; Buf: PAnsiChar; var DataLen: Integer);
begin
  ShowMessage('получил');
end;

ничего не приходит..


Сергей М.   (2010-05-11 23:53:00) [20]

Ну вот тебе и ошибка - по завершению обработки события OnAccept сервер разрывает соединение с клиентом.
Это абсолютно нормальное поведение TTCPServer'а.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо