Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Программирование передачи данных по сети Интернет


Автор: Glorius 13.3.2009, 15:07
Добрый день.
Есть идея создать программу обмена сообщениями и файлами наподобие ICQ между двумя удаленными компьютерами по сети. Не очень хорошо разбираюсь в программировании, создал несколько программок, достаточно функциональных, но далеко не спец и под интернет не программировал вообще. Подскажите какими средствами это все делается, какие темы нужно изучить, какими компонентами нужно пользоваться. 
Спасибо.

Автор: UniBomb 13.3.2009, 18:00
http://sources.ru/builder/chat97.shtml реализации с исходниками.

Автор: Glorius 13.3.2009, 23:15
Цитата(UniBomb @  13.3.2009,  18:00 Найти цитируемый пост)
Пример реализации с исходниками.

Спасибо посмотрю. Но это пример чата в локальной сети? А в сети интернет?

Мне бы элементарный пример для понимания принципа работы. Что нибудь типа поля Мемо, поля Edit и кнопки на форме клиентского приложения. Функциональность которого бы заключалась по нажатию кнопки в отправке строчки из поля Edit в поле Мемо своего приложения, ну и собственно в поле Мемо приложения удаленного пользователя. Связь через интернет.

Автор: Alca 13.3.2009, 23:17
HTTP?

Добавлено через 4 минуты и 32 секунды
Цитата

какими средствами это все делается

Indy

Автор: Glorius 14.3.2009, 00:09
Цитата(Alca @  13.3.2009,  23:17 Найти цитируемый пост)
Indy

а поподробнее? может какие примеры, ссылки где об этом доходчиво написано

Автор: Alca 14.3.2009, 00:17
C:\Program files\Borland\CBuilder6\Examples\Indy

Автор: Glorius 15.3.2009, 14:35
Что-то не получается наладить связь по сети интернет. 
Создаю сервер на компьютере со статическим ай-пи, задав порт (как я понял это может быть любай цифра из определенного диапазона, я пробовал 4964, 5500, 6701).
Пробую подключиться клиентом с другого компьютера, задав в свойство Host ай-пи сервера и в свойство Port - порт сервера.
В событии клиента при подключении к серверу записываю вывод сообщения что присоединился.
В событии сервера при подключении клиента записываю вывод сообщения, что присоединился клиент.

Так вот нажав на копку "Подключиться к серверу" в клиенте нет сообщения об успешности подключения, соответственно на сервере тоже, то есть связь не установлена.
Код
void __fastcall TForm1::BCreateClick(TObject *Sender)
{
ServerSocket1->Port = StrToInt(EPort->Text);
BCreate->Enabled = false;
BJoin->Enabled = false;
BDisconnect->Enabled = true;
ServerSocket1->Open();
Memo1->Lines->Add("Сервер создан");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BJoinClick(TObject *Sender)
{
ClientSocket1->Host = CBHost->Text;
ClientSocket1->Port = StrToInt(EPortClient->Text);
BCreate->Enabled = false;
BJoin->Enabled = false;
BDisconnect->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BDisconnectClick(TObject *Sender)
{
if (ServerSocket1->Active)
  {
    ServerSocket1->Close();
    Memo1->Lines->Add("Сервер отключен");
  }
if (ClientSocket1->Active)
  {
    ClientSocket1->Close();
  }
BCreate->Enabled = true;
BJoin->Enabled = true;
BDisconnect->Enabled = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ClientConnect(TObject *Sender,
      TCustomWinSocket *Socket)
{
Memo1->Lines->Add("Присоединился клиент");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ClientDisconnect(TObject *Sender,
      TCustomWinSocket *Socket)
{
Memo1->Lines->Add("Клиент отсоединился");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Connect(TObject *Sender,
      TCustomWinSocket *Socket)
{
Memo1->Lines->Add("Присоединился к серверу");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Disconnect(TObject *Sender,
      TCustomWinSocket *Socket)
{
Memo1->Lines->Add("Отключился от сервера");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
ServerSocket1->Close();
ClientSocket1->Close();
}



Что я делаю не так?

Автор: Glorius 15.3.2009, 15:53
Мда, собственно забыл активизировать клиента.
Код
void __fastcall TForm1::BJoinClick(TObject *Sender)
{
ClientSocket1->Host = CBHost->Text;
ClientSocket1->Port = StrToInt(EPortClient->Text);
ClientSocket1->Open();
BCreate->Enabled = false;
BJoin->Enabled = false;
BDisconnect->Enabled = true;
}



Теперь выскакивает ошибка "Asynchronous socket error 10060".

Автор: Alca 15.3.2009, 19:49
Цитата

Теперь выскакивает ошибка "Asynchronous socket error 10060".

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

Автор: Glorius 15.3.2009, 20:03
Цитата(Alca @  15.3.2009,  19:49 Найти цитируемый пост)
Попытка установить соединение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или было разорвано уже установленное соединение из-за неверного отклика уже подключенного компьютера. 

Это я уже понял, а вот как это побороть пока не придумал.

Автор: Glorius 15.3.2009, 20:29
В дополнение.
Изучая тему нашел информацию что связь еще зависит от типа доступа в интернет. Проверяю работоспособность на двух компьютерах подключенных по ADSL, у одного ай-пи адрес динамический, у второго (сервера) - статический.

Автор: xvr 16.3.2009, 19:45
А Firewall'а там по пути нет случайно? 

Автор: Glorius 16.3.2009, 19:53
Цитата(xvr @  16.3.2009,  19:45 Найти цитируемый пост)
А Firewall'а там по пути нет случайно? 

есть, но при отключенных фаерволах та же ошибка

Автор: Dem_max 16.3.2009, 20:33
Glorius
Цитата
Теперь выскакивает ошибка "Asynchronous socket error 10060".

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

Автор: Glorius 16.3.2009, 20:53
Цитата(Dem_max @  16.3.2009,  20:33 Найти цитируемый пост)
Сокет должен работать в асинхронном режиме, а получается так что ты пытаешься его заставить работать в синхронном режиме что присуще консольным приложениям сожержащим основной поток.

И как мне заставить его работать в асинхронном режиме?

Автор: Anikmar 16.3.2009, 22:04
А сервер к нету подключен через ADSL модем или роутер? Если через Роутер - в каком режиме он работает мост или роутер?

Автор: Glorius 16.3.2009, 22:11
Цитата(Anikmar @  16.3.2009,  22:04 Найти цитируемый пост)
А сервер к нету подключен через ADSL модем или роутер? Если через Роутер - в каком режиме он работает мост или роутер?

ADSL modem D-Link 2500U.

Автор: Anikmar 16.3.2009, 22:16
Так вроде он и в режиме роутера работать может. Глянтьте на всякий случай, а то может тут зря воды столько развели, а ларчик бах и откроется.

Автор: Glorius 16.3.2009, 22:22
Цитата(Anikmar @  16.3.2009,  22:16 Найти цитируемый пост)
Так вроде он и в режиме роутера работать может. Глянтьте на всякий случай, а то может тут зря воды столько развели, а ларчик бах и откроется.

а как это определить?

Автор: Anikmar 16.3.2009, 22:29
Цитата(Glorius @  16.3.2009,  22:22 Найти цитируемый пост)
а как это определить? 

Если вы намерены писать достаточно серьезное сетевое приложение, то просто обязаны узнать как работают роутеры, что такое NAT и т.п.
Зайдите в настройки роутера и посмотрите:
1. В каком режиме он находится (мост или роутер)
2. Включен ли у него аппаратный файрволл
3. Попробуйте в любом случае установить прямой рефорвардинг нужных вам портов.

Должна же быть к нему инструкция? Конкретно эту модель я ни разу не настраивал - думаю информации в нете по ней уйма. Просто на сколько я помню он поддерживает беспроводную сетку тогда и роутить он просто обязан уметь.

Автор: Glorius 16.3.2009, 22:33
Anikmar, вы можете кратко и в достаточном объеме пояснить какие именно настройки ДОЛЖНЫ быть установлены на модеме сервера и клиента, в частности как определить режим (мост или роутер) и как его установить, включен ли файервол и как установить прямой рефорвардинг нужных мне портов?
Или мне нужно глубоко изучать тему? Приложение предполагается не сложное, на уровне обмена информацией между 2 компьютерами.

Автор: Anikmar 16.3.2009, 22:44
Цитата(Glorius @  16.3.2009,  22:33 Найти цитируемый пост)
Anikmar, вы можете кратко и в достаточном объеме пояснить какие именно настройки ДОЛЖНЫ быть установлены на модеме сервера и клиента, в частности как определить режим (мост или роутер) и как его установить, включен ли файервол и как установить прямой рефорвардинг нужных мне портов?
Или мне нужно глубоко изучать тему? Приложение предполагается не сложное, на уровне обмена информацией между 2 компьютерами. 

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

Могу только посоветовать:
http://bigus.ru/other/bridge/index.html, http://torrents.ru/forum/viewtopic.php?t=1169777, http://www.ellink.ru/co/adsl/etc/dlink_2500u.php

А главное, используйте http://www.google.ru/

Автор: Glorius 16.3.2009, 22:51
Anikmar, да, как настроить - это можно нагуглить, но вам спасибо. Я же имел ввиду ЧТО ИМЕННО нужно настроить. То есть, нужен мост или роутер, нужно устанавливать прямой рефорвардинг портов или нет.

Автор: Anikmar 16.3.2009, 22:57
Вне зависимости сложное сетевое приложение вы будете писать или не очень - вы собираетесь связать два компьютера через интернет. А значит, вы как минимум должны знать как адресуются компьютеры в данной сети.

Вкратце расскажу про NAT. В виду того, что общее количество IP адресов ограничено и быстро заканчивается, а IP v6 еще не известно когда получит широкое распространение (слишком много аппаратных роутеров необходимо поменять) наиболее широкое распространение получил NAT - способ ретрансляции сетвых адресов при помощи роутеров.

Суть работы роутера достаточно проста: как только один из компов пытается подключится к другому (указывает его IP и порт) реально этот запрос сначала идет к роутеру (шлюзу). Сам роутер имеет свой IP и виден всему интернету. Он перенаправляет ваш запрос на указанный адрес. В случае с одним компом - все в порядке. А если 10 компов в локалке пытаются загрузить странички с одного сервака? Ведь сервак должен ответить, а для него - это всего лишь 1 адрес IP, который имеет роутер. И сервак в интернете никак не сможет понять к какому конкретно компу за роутером он должен обратиться. Это и есть NAT - роутер динамически меняет IP заголовок и подставляет фиктивные адреса портов, а затем при поступлении на эти порты ответов транслирует назад.

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

Это вкратце и по возможности доходчиво в меру моих знаний. Я не гуру, поэтому сказал, что сам понимаю.

Добавлено через 3 минуты и 6 секунд
Цитата(Glorius @  16.3.2009,  22:51 Найти цитируемый пост)
Anikmar, да, как настроить - это можно нагуглить, но вам спасибо. Я же имел ввиду ЧТО ИМЕННО нужно настроить. То есть, нужен мост или роутер, нужно устанавливать прямой рефорвардинг портов или нет. 


Поставьте в режим моста и отключите файрволл.

Дополнительно (по идее уже не нужно, но сделайте):
Включите режим порт форвардинг на все порты, все пакеты напрямую на компьютер сервера. Он должен позволять задавать порты по диапазону - для всех протоколов все диапазоны перенапрвьте на сервер.

Автор: Glorius 16.3.2009, 23:05
Anikmar, спасибо, попробую, завтра отпишу о результатх.

Автор: Glorius 17.3.2009, 15:43
Anikmar, все настройки серверного модема такие как показаны по вашей первой ссылке, то есть настроен модем как мост (bridge).

А вот как выглядит статусное окно модема клиентской машины. Тоже мост. При отключенных фаерволах пинг не проходит как и не проходил раньше.

Автор: Anikmar 17.3.2009, 15:58
А можете сказать, какой IP у вашего сервера? (Если нет военной тайны, конечно).

Автор: Glorius 17.3.2009, 17:05
Цитата(Anikmar @  17.3.2009,  15:58 Найти цитируемый пост)
А можете сказать, какой IP у вашего сервера? (Если нет военной тайны, конечно).

впринципе нет, только я дам адрес клиентской машины, она у меня под рукой, а в моей программе нету особой разницы кто именно будет сервером, IP-адрес 86.57.178.37.
Если вы не сильно заняты, может поможете мне справиться с этой проблемой в ICQ? Мой номер 352336167

Автор: Anikmar 17.3.2009, 17:08
Попробуем. Я свяжусь с вами примерно через 30 минут - когда до дому доеду

Автор: KTatsu 11.5.2009, 10:11
Тема относительно не старая, так, что задам свой вопрос сюда, вместо того, чтобы писать новый пост, тем более вопрос по теме.

Тоже возникла проблеммка с передачей данных по сети.
Я хочу сделать на своей машине сервер, а у друга будет клиент, проблема, с которой я столкнулся - маршрутеризаторы.
По LAN отлично работает, а вот из внешней сети не знаю как присоединиться.
Использовал компоненты TClientSocket и TServerSocket.
Дело в том, что у моего провайдера сидят несколько клиентов на одном IP через адсл, дальше мой домашний роутер и домашняя сеть.
Вопрос, как связаться с сервером при таком раскладе? Понимаю, что существует НАТ, но как им воспользоваться?
Или как должно выглядеть обращение в сеть? Я должен с клиента отправить запрос, содержащий все IP которые стоят на пути к серверу?

Поиском пользовался, есть похожие темы, но самого ответа так и не нашел.

Автор: xvr 11.5.2009, 11:13
С одной стороны должен быть внешний статический IP адрес. Противоположная сторона должна открывать TCP соединение с этим IP. Иначе никак  smile 

Автор: KTatsu 11.5.2009, 19:18
Не понял... IP у меня статический.
Цитата

Противоположная сторона должна открывать TCP соединение с этим IP.
Т.е. сервер или клиент?
Вот к примеру, щас мне друг послал файл через квип напрямую, у меня написано следующее в квипе:

     Входящий файл:  123.rar
     Размер:  3,89 Мб
     Внешний IP:  92.112.102.***
     Внутренний IP:  192.168.1.*, 92.112.102.***

Т.е. для передачи, всетаки клиент использует IP, как внешний, так и внутренний.
А вот в случае когда я другу передаю файл, у него пишет так:

     Входящий файл:  123.rar
     Размер:  3,89 Мб
     Внешний IP:  213.141.151.***
     Внутренний IP:  127.0.0.1

Этого я вообще не могу понять, чепуха какая-то с внутренним smile 
Так что мне делать? Если указывать все IP на пути от провайдера до указанного компа, куда их вписывать, если графа под адрес одна? писать через запятую адреса чтоли? smile 

Автор: xvr 12.5.2009, 09:24
Цитата(KTatsu @ 11.5.2009,  19:18)
Не понял... IP у меня статический.

IP должен быть не только статический, он еще должен быть доступен снаружи
Цитата

Цитата

Противоположная сторона должна открывать TCP соединение с этим IP.
Т.е. сервер или клиент?
Это не важно (конечно лучше будет, если внешний IP будет у сервера, иначе придется заставлять сервер конектится к клиенту, что несколько сложнее  smile )
Цитата

Вот к примеру, щас мне друг послал файл через квип напрямую, у меня написано следующее в квипе:

     Входящий файл:  123.rar
     Размер:  3,89 Мб
     Внешний IP:  92.112.102.***
     Внутренний IP:  192.168.1.*, 92.112.102.***

Т.е. для передачи, всетаки клиент использует IP, как внешний, так и внутренний.
IP используется один и тот же. Это как раз задача шлюзов (и NAT'ов) по дороге преобразовать IP и порт так, что бы была возможна 2х сторонняя связь. С точки зрения установления соединения нужно просто открыть порт (с определенным номером) на сервере по заданному IP , т.е. ничем от соединения в локалке не отличается. 
Но этот IP сервера должен быть, и должен быть доступен снаружи.


Цитата

А вот в случае когда я другу передаю файл, у него пишет так:

     Входящий файл:  123.rar
     Размер:  3,89 Мб
     Внешний IP:  213.141.151.***
     Внутренний IP:  127.0.0.1

Этого я вообще не могу понять, чепуха какая-то с внутренним smile 
Это так называемый loopback IP, обозначает свой собственный компьютер. Нигде, кроме самого компьютера, смысла не имеет.
Цитата

Так что мне делать? Если указывать все IP на пути от провайдера до указанного компа, куда их вписывать, если графа под адрес одна? писать через запятую адреса чтоли? smile
Писать один внешний адрес

Автор: KTatsu 12.5.2009, 13:42
Цитата

Писать один внешний адрес
Не получается с одним лишь внешним адресом... Может другие компоненты нужно использовать? Я пытаюсь через TServerSocket и TClientSocket.
Цитата

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

Автор: xvr 12.5.2009, 16:19
Цитата(KTatsu @ 12.5.2009,  13:42)
Цитата

Писать один внешний адрес
Не получается с одним лишь внешним адресом...

Если этот один ВНЕШНИЙ адрес СУЩЕСТВУЕТ - то должно получится. Если его нет - то облом, нужно менять архитектуру построения системы В ПРИНЦИПЕ. Например использовать внешние сервера или proxy
Цитата

 Может другие компоненты нужно использовать? Я пытаюсь через TServerSocket и TClientSocket.
Компонентами здесь ничего не решить
Цитата

Цитата

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

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)