Модераторы: Snowy, Poseidon, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> tcpserver и tcpclient. ЧАТ 
:(
    Опции темы
boobie
Дата 13.6.2013, 08:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 162
Регистрация: 16.9.2011

Репутация: нет
Всего: нет



Здравствуйте! Экспериментирую с сетью. Написал программу, отдаленно напоминающую чат: 2 поля ввода (memo1 и memo2), 1 кнопка (button1), TcpServer1, Tcpclient1.
TcpServer1.Localport поставил 7000. Такой же порт поставил в TcpClient1.RemotePort. TcpClient1.Remotehost выставил 127.0.0.1
Код программы:
Код

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Web.Win.Sockets, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Memo2: TMemo;
    Button1: TButton;
    TcpServer1: TTcpServer;
    TcpClient1: TTcpClient;
    procedure FormCreate(Sender: TObject);
    procedure TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
begin
  for i:=0 to memo1.Lines.Count-1 do
  begin
    tcpclient1.Sendln(memo1.Lines[i]);
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
tcpserver1.Close;
tcpclient1.Disconnect;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
tcpserver1.BlockMode:=bmthreadblocking;
tcpserver1.Open;
tcpclient1.Open;
end;

procedure TForm1.TcpServer1Accept(Sender: TObject;
  ClientSocket: TCustomIpClient);
var s:string;
begin
  s:=ClientSocket.Receiveln;
  memo2.Lines.Add(s);
end;

end.

При создании формы все открываем, при закрытии - рассоединяем, при нажатии на кнопку - отсылаем все строки из memo1 с помощью цикла и tcpclient1.Sendln(memo1.Lines[i]);. Сервер прослушивает, если что-нибудь придет, то эту строку добавляем в memo2.
И вот вопросы:
1. Не работает! Приходит только одна строка, только один раз. Потом сообщения не приходят. Каким образом запускается событие TcpServer1Accept? Я думал, что для каждой приходящей строки, отосланной с помощью Sendln, оно генерируется заново. 
Почему вот так:
Код

procedure TForm1.TcpServer1Accept(Sender: TObject;
  ClientSocket: TCustomIpClient);
var s:string;
begin
  s:=ClientSocket.Receiveln;
  while s <> '' do
  begin              
    memo2.Lines.Add(s);
    s:=ClientSocket.Receiveln;
  end;
end;

работает как надо?
2. В книжках после каждой отправки сообщения авторы разрывают связь, перед отправкой сообщения устанавливают заново. Стоит ли это делать при создании реальных приложений? Т.е. есть ли смысл перед каждой отправкой сообщений коннектится, а потом разрывать связь?
PM   Вверх
Poseidon
Дата 13.6.2013, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 4
Всего: 133



Оно поэтому и Receiveln, что получает только одну строчку (line). Почему-то такие функции как Readln и Writeln подобных вопросов не вызывают...


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Akella
Дата 13.6.2013, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 4
Всего: 329



Я помню, в примерах с дельфи поставлялся готовый проект чата.
PM MAIL   Вверх
boobie
Дата 13.6.2013, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 162
Регистрация: 16.9.2011

Репутация: нет
Всего: нет



Akella, да не нужен мне готовый чат, я с сетью разбираюсь  smile 

Poseidon, все равно не пойму - отправляется 3 строки, например, а почему метод TcpServer1Accept вызывается всего 1 раз, принимает одну строку (это логично - ReciveLN)... А при последующих нажатиях - ВООБЩЕ ничего не принимает. Почему так?



Это сообщение отредактировал(а) boobie - 13.6.2013, 13:11
PM   Вверх
Akella
Дата 13.6.2013, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 4
Всего: 329



Цитата(boobie @  13.6.2013,  13:02 Найти цитируемый пост)
Akella, да не нужен мне готовый чат, я с сетью разбираюсь  smile 

вот и разбирайся на основе готового рабочего примера ;)
PM MAIL   Вверх
boobie
Дата 13.6.2013, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 162
Регистрация: 16.9.2011

Репутация: нет
Всего: нет



Ну, Akella, твой 18000-ый пост мог быть и лучше!  smile 
Я не случайно привел код, который я взял из работающего примера:
Код

procedure TForm1.TcpServer1Accept(Sender: TObject;
  ClientSocket: TCustomIpClient);
var s:string;
begin
  s:=ClientSocket.Receiveln;
  while s <> '' do
  begin              
    memo2.Lines.Add(s);
    s:=ClientSocket.Receiveln;
  end;
end;

он работает... А я не понимаю почему... Почему так работает, а в "моем" случае - нет. Сам механизм не понятен
PM   Вверх
Poseidon
Дата 13.6.2013, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 4
Всего: 133



boobie, ты посылаешь в цикле
Код

procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
begin
  for i:=0 to memo1.Lines.Count-1 do
  begin
    tcpclient1.Sendln(memo1.Lines[i]);
  end;
end;

т.е. выполняешь Sendln несколько раз. Почему ты думаешь, что прочитать это нужно за один Receiveln?


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Akella
Дата 13.6.2013, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 4
Всего: 329



ну так трассируй, посмотри что и как выполняется с циклом и без
PM MAIL   Вверх
boobie
Дата 13.6.2013, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 162
Регистрация: 16.9.2011

Репутация: нет
Всего: нет



Т.е. процедура TcpServer1Accept запускается один раз и не выходит из процедуры, пока все данные не будут считаны? Так?
PM   Вверх
Akella
Дата 13.6.2013, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 4
Всего: 329



А что, F1 выламана?
PM MAIL   Вверх
boobie
Дата 13.6.2013, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 162
Регистрация: 16.9.2011

Репутация: нет
Всего: нет



Эмм... Получается, что данная процедура вызывается сразу после подключения клиента... Создается очередь для хранения клиентских запросов. Эта очередь обслуживается в данной процедуре. Это я понял из справки, бат ай донт спик инглиш. Так? А что происходит с очередью, если ее не обработать в этой процедуре?
PM   Вверх
Akella
Дата 14.6.2013, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 4
Всего: 329



ничего не происходит, наверное )))
PM MAIL   Вверх
boobie
Дата 14.6.2013, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 162
Регистрация: 16.9.2011

Репутация: нет
Всего: нет



Дело в том, что если не убрать эту очередь из строк, то в следующий раз захода в процедуру не будет...
PM   Вверх
Akella
Дата 14.6.2013, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 4
Всего: 329



PM MAIL   Вверх
boobie
Дата 14.6.2013, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 162
Регистрация: 16.9.2011

Репутация: нет
Всего: нет



Да, там цикл вставлен... Ничего особенного. Пока есть очередь - получай строку и закидывай в мемо. Проблемы начинаются, если очередь большая и с полученными данными надо что-то делать. Без многопотока тогда не обойтись. Да и поведение TcpServer1Accept  неадекватное.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1056 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.