![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
TCPClient вторая посылка не проходит
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'а.