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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Соединение по интернету между сервером и клиентом 
:(
    Опции темы
yogin
Дата 8.7.2008, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Всех категорически приветствую. Сразу скажу что по своему вопросу целую неделю рою инет, книги и мнения знакомых. НИЧЕГО!
Первоочередная цель вот о чём: Необходимо создать соединение ПО ИНТЕРНЕТУ по средствам компонентов idTCP(Server/Client) с банальной возможностью передачи хотя бы строк!
есть следующие наработки - небольшое изменение того что есть в DRKB:
СЕРВЕР
Код

{#######################################################################################################}
procedure TForm1.N2Click(Sender: TObject);  // запуск серва
begin
  Server.Active := true;
  protocol.Lines.Add('===============Запуск Серва================');
end;

{#######################################################################################################}
procedure TForm1.N3Click(Sender: TObject);  // отпуск
begin
  Server.Active := false;
  protocol.Lines.Add('===============Отпуск Серва================');
end;

{#######################################################################################################}
procedure TForm1.ServerConnect(AThread: TIdPeerThread);
var
  NewClient: PClient;
begin
  GetMem(NewClient, SizeOf(TClient));
  NewClient.DNS := AThread.Connection.LocalName;
  NewClient.Connected := Now;
  NewClient.LastAction := NewClient.Connected;
  NewClient.Thread := AThread;
  AThread.Data:=TObject(NewClient);
  try
    //Clients.LockList.Add(NewClient);          И ДЛЯ ЧЕГО ЭТО ТАК И НЕПОНЯТНО... И БЕЗ ЭТОГО ВСЁ НОРМ
  finally
    //Clients.UnlockList;
  end;
  Protocol.Lines.Add(TimeToStr(Time)+' Соединение компьютера: "'+NewClient.DNS+'"');
end;

{#######################################################################################################}
procedure TForm1.ServerDisconnect(AThread: TIdPeerThread);
var
  ActClient: PClient;
  ConnN: integer;
begin
  ActClient := PClient(AThread.Data);
  Protocol.Lines.Add (TimeToStr(Time)+' Отсоединение компьютера: "'+ActClient^.DNS+'"');
  try
    //Clients.LockList.Remove(ActClient);    ВОТ ИЗ-ЗА ЭТОГО ВАЩЕ ОШИБКА В ПОТОКАХ ПРИ ОТКЛЮЧЕНИИ ПРОИСХОДИТ
  finally
    //Clients.UnlockList;
  end;
  FreeMem(ActClient);
  AThread.Data := nil;
end;

{#######################################################################################################}
procedure TForm1.ServerExecute(AThread: TIdPeerThread);
const
  cmRegisterComp = 'REGISTER';                     
  cmUnRegisterComp = 'UNREGISTER';
var
  ActClient, RecClient: PClient;
  CommBlock, NewCommBlock: TCommBlock;
  RecThread: TIdPeerThread;
  i, ConnN: Integer;
  itmp: integer;
begin
  if not AThread.Terminated and AThread.Connection.Connected then
  begin
    AThread.Connection.ReadBuffer (CommBlock, SizeOf (CommBlock));
    ActClient := PClient(AThread.Data);
    ActClient.LastAction := Now; // update the time of last action
    // Регистрация компьютера
    if (UpperCase(CommBlock.Command) = UpperCase(cmRegisterComp)) then
    begin
      Protocol.Lines.Add(' Регистрация компьютера: '+UpperCase(CommBlock.ComputerName));
      meConnected.Lines.Add(UpperCase(CommBlock.ComputerName));
      //RefreshConnected;
      //RefreshConnectedComps;
      //RefreshGolosProcess;  // ??????????????
      // AThread.Connection.WriteBuffer (NewCommBlock, SizeOf (NewCommBlock), true); // and there it goes...
    end
    // Удаление компьютера
    else if (UpperCase(CommBlock.Command) = UpperCase(cmUnRegisterComp)) then
    begin
      Protocol.Lines.Add(' Удаление компьютера: '+UpperCase(CommBlock.ComputerName));
      //ConnN:=FindConnComp(UpperCase(CommBlock.ComputerName)); // ?????
      if ConnN<>-1 then meConnected.Lines.Delete(ConnN);
      //RefreshConnected;
      //RefreshConnectedComps;
      //RefreshGolosProcess;
      // AThread.Connection.WriteBuffer (NewCommBlock, SizeOf (NewCommBlock), true); // and there it goes...
    end
    // Регистрация ответов
    else
    begin // unknown command given
      Protocol.Lines.Add (TimeToStr(Time)+' Unknown command from "'+CommBlock.MyUserName+'": '+CommBlock.Command);
      NewCommBlock.Command := 'DIALOG'; // the message should popup on the client's screen
      NewCommBlock.MyUserName := '[Server]'; // the server's username
      NewCommBlock.Msg := 'I dont understand your command: "'+CommBlock.Command+'"'; // the message to show
      NewCommBlock.ReceiverName := '[return-to-sender]'; // unnecessary
      AThread.Connection.WriteBuffer (NewCommBlock, SizeOf (NewCommBlock), true); // and there it goes...
    end;
  end;

end;



КЛИЕНТ
Код

{##############################################################################}
procedure TForm1.N2Click(Sender: TObject);// коннект
var
  ClientHandleThread  : TClientHandleThread;
begin
  try
    M1.Lines.Add('===Подключение к серверу===');
    //Client.Host:=DBInfo.IBaseServerName;                              ЧТО ЗА ПЕРЕМЕННАЯ DBInfo.IBaseServerName!?
    Client.Connect(10000); // in Indy < 8.1 leave the parameter away
    ClientHandleThread := TClientHandleThread.Create(True);
    ClientHandleThread.Cli:=Client;
    //ClientHandleThread.EventMest:=FEventMess;                    ЧТО ЗА ПЕРЕМЕННАЯ FEventMess
    ClientHandleThread.Str:=M1.Lines;
    ClientHandleThread.FreeOnTerminate:=True;
    ClientHandleThread.Resume;
    //RegComp;
  except
    on E: Exception do MessageDlg ('Ошибка подключения:'+#13+E.Message, mtError, [mbOk], 0);
  end;

end;

{##############################################################################}
procedure TForm1.N3Click(Sender: TObject);// дисконнект
begin
  try
    M1.Lines.Add('===Disconnection process===');
    //Client.Host := EditHost.Text;  это я вводил айпи в едит
    if client.Connected then
    begin
      Client.Disconnect;
      M1.Lines.Add('===Client its Disconnected===');
    end;
  except
    on E: Exception do MessageDlg('Ошибка подключения: '+E.Message, mtError, [mbOk], 0);
  end;
end;

{##############################################################################}
procedure TForm1.N5Click(Sender: TObject);
begin
  Form1.Close;
end;

procedure TForm1.E1KeyPress(Sender: TObject; var Key: Char);
var
  CommBlock :TCommBlock;
  st1:string[100];
begin
  if (E1.Text<>'')and(key=#13)and(length(E1.text)<100) then
  begin
    CommBlock.Command:=Uppercase('message');
    CommBlock.MyUserName:=Client.LocalName;
    CommBlock.Msg:=E1.Text;
    CommBlock.ReceiverName:=E1.Text;
    CommBlock.ComputerName:=Uppercase(Client.LocalName);

    //Client.WriteBuffer(CommBlock, SizeOf(CommBlock), true);
    st1:=E1.Text;
    Client.WriteBuffer(st1, SizeOf(st1), true);
    E1.Text:='';
  end;
end;


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

type
  PClient = ^TClient;

{RECORDS}
  TClient = record
    DNS            :String[20];          { Hostname }
    PeerIP        :string[15];    { IP клиента }
    TakeShot    :boolean;     
    Connected,                     { Time of connect }
    LastAction   :TDateTime; { время последней активности }
    Thread        :Pointer; { Pointer на поток }
  end;


Потом так и остались неизвестными строки которые я прокомментил БОЛЬШИМИ БУКВАМИ  smile 
вообщем кое как добился чтобы этот пример работал, но он работает только В СЕТИ! и теперь вопрос на миллион долларов - 
что нужно доделать чтобы это всё чудо, которое мне нравится(из-за потоков и передачи переменной-записи через буфер) РАБОТАЛО ПО ИНТЕРНЕТУ! именно: какой айпи куда вписывать(серверу/клиенту)? есть мнение что нужно клиенту прописывать внешний айпи сервера, но когда я так делаю со своим примером, то клиент висне, как буд-то пакет не доходит до сервера. В курсе о жизни пакета - его первый байт, может его где-то в параметрах компонентов прописать, чтобы он был не 1, как требуется для локалки, а больше...


Особенности подключения:
Хочу для начала протестировать это всё с сервером на моём компе, у меня АДСЛ, внешний айпи могу узнать легко и сказать тому у кого будет клиент - моему знакомому, он введёт куда надо и законнектится ко мне. Вообщем так я и тестил все эти неудачные попытки((. 
А потом уже перемещу серв на статичный айпи(сразу немогу потому что нужны деньги) и всё такое, вообщем мне нужно сначало всё протестить.

Очень нужна помощь в этом вопросе, я уже незнаю что делать! у меня из-за этого ступора вся работа встала!

После того как разъяснится мой случай, то настаиваю о добавлении получившегося живого примера в DRKB.

Это сообщение отредактировал(а) yogin - 8.7.2008, 12:27
PM MAIL   Вверх
yogin
Дата 8.7.2008, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Проблема соединения решина. Поясню причину для тех кто задался таким же вопросом:

Дело в том, что, при тестировании соединения, для сервера я ошибочно использовал свой компьютер, у которого внешний IP является динамическим.
При запросе с клиента пакет получает провайдер и далее уничтожает его, т.к. не знает что с ним делать, потому что внешний IP не ассоциирован с моим компьютером. Следовательно мой комп не мог выступать в роли сервера. Запустили сервер на компьютере с непосредственным внешним IP, у клиента параметру Host нужно присвоить IP сервера ну и одинаковые порты конечно и вуаля! всё контачит.

Остаётся открытым вопрос о неизвестных переменных в приведённом мной примере из DRKB ???
PM MAIL   Вверх
SneG0K
Дата 9.7.2008, 06:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Max Mara
***


Профиль
Группа: Завсегдатай
Сообщений: 1887
Регистрация: 1.12.2007
Где: Wis Dells

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



Цитата(yogin @  8.7.2008,  17:30 Найти цитируемый пост)
ну и одинаковые порты конечно

Порт назначить можно только серверу. Клиенту от этого не холодно не жарко должно быть. Посмотри например как работает браузер. Он всегда коннектится к 80 порту (или почти всегда), но с абсолютно разных портов. 
PM WWW Skype   Вверх
yogin
Дата 10.7.2008, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(SneG0K @ 9.7.2008,  06:21)
Порт назначить можно только серверу. Клиенту от этого не холодно не жарко должно быть. Посмотри например как работает браузер. Он всегда коннектится к 80 порту (или почти всегда), но с абсолютно разных портов.

хм, не обращал внимания, но тогда зачем у клиентских компонентов есть параметр Port, если он не обязателен?

Это сообщение отредактировал(а) yogin - 10.7.2008, 00:15
PM MAIL   Вверх
Virtuals
Дата 10.7.2008, 06:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



yogin, 
Цитата
хм, не обращал внимания, но тогда зачем у клиентских компонентов есть параметр Port, если он не обязателен?


 smile 
немного теории:...
в обще случае полный! адресат при применении протокоа TCP-IP выглядит так:

MAC (физический адрес сетевого адаптера) - IP (адрес по протоколу IP) - PORT (адрес по протоколу TCP)

отсюда:

серверу обязательно указывать порт на котором слушать (ну иначе как операционка поймет кому пришел пакет)
клиенту указывается порт на который соединится (такой-же как у сервера), 
и порт "обратного адреса" smile (ну в письме вы же указываете обратный адрес куда слать ответ), так вот если указать 0 то операционка сама вам выдаст произвольный порт для обратного потока данных сервер->клиент (не время TCP-IP сессии)
хотя можете и назначить его сами. (лиж бы данный порт был свободен в данный момент времени на клиентской машине)
PM MAIL ICQ   Вверх
yogin
Дата 12.7.2008, 21:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



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

Запрещено:

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

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

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

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

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


 




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


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

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