Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > Клиент-сервер: передача данных через интернет


Автор: Saviour 28.3.2010, 12:52
Общеизвестная простая задача (реализация эхо-сервера). Есть локалка и выход в интернет. IP-адрес в интернете динамический (привязала его к хосту через dyndns). Кусок кода сервера:
Код

#include <winsock2.h>
#define PORT 2342
...   ...   ...
  SOCKET server_socket;
  sockaddr_in local_addr;
...   ...   ...
  server_socket=socket(AF_INET,SOCK_STREAM,0);
  local_addr.sin_family=AF_INET;
  local_addr.sin_port=htons(PORT);
  hostent *h;
  char *SERVER="server.homedns.org";
  in_addr IP_addr;
  char *IP;
//gethostname(SERVER, 128); //для локалки
  h=gethostbyname(SERVER);
  Text_Out("Имя сервера: ");
  cout<<h->h_name<<endl;
  IP_addr.S_un.S_un_b.s_b1=h->h_addr_list[0][0];
  IP_addr.S_un.S_un_b.s_b2=h->h_addr_list[0][1];
  IP_addr.S_un.S_un_b.s_b3=h->h_addr_list[0][2];
  IP_addr.S_un.S_un_b.s_b4=h->h_addr_list[0][3];
  IP=inet_ntoa(IP_addr);
  Text_Out("IP-адрес сервера: ");
  cout<<IP<<endl;
  local_addr.sin_addr.s_addr=inet_addr(IP);
  if(bind(server_socket,(sockaddr*)&local_addr,sizeof(local_addr)))
    return;
...   ...   ...

Если раскомментить строку, то все прекрасно: определяю свой сетевой адрес (192.168.x.x; значение h->h_name - сетевое имя компа; вроде все нормально), связываю с ним сокет. Код клиента аналогичный. Таким образом, в локалке все работает.

Не получается связать сокет с внешним IP. Запускаю сервер - bind(...) возвращает не ноль. Где я натупила - в коде или в настройках DynDNS Updater (которые я не трогала за исключением того, что в Settings->Groups добавила свой акк на dyndns.com и выбрала нужный хостнейм)? Нужно ли пробрасывать порт 2342 в настройках модема (на всякий случай пробросила и разрешила его в брандмауэре) или можно без этого обойтись?

PS: bind возвращает ошибку 10049 - WSAEADDRNOTAVAIL

Автор: GoldFinch 31.3.2010, 19:04
Saviour, может gethostbyname возвращает не один ip, а первый в списке просто не подходит?

Автор: darkmamba 31.3.2010, 19:22
gethostbyname может вообще ничего не возвратить, нужно поставить проверку.
Помоему биндить нужно на свой внутренний а на роуторе уже разруливать, поидее забиндится должно без косяков -> ошибка в определении ИП ?

Автор: Олег2005 31.3.2010, 20:20
Обычно принято биндить на серверный адрес INADDR_ANY - интерфейс выбирает сам стек.
И для сервера не необходимости вызывать  
h=gethostbyname(SERVER);
Никакой......
Если хочется узнать IP-адрес, по которому прошел bind() - getsockname()

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