Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Соединение с локалхостом не работает, А с нелокалхостом - работает 
:(
    Опции темы
VirtualVoid
Дата 1.10.2010, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Добрый день!

Решил освоить сокеты в Linux. Вот простые клиент и сервер:

cli.cpp:
Код

#include <cstdio>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <cstring>

int main(int argc, char **argv)
{
        if(argc!=2)
        {
                printf("Bad args.\n");
                return -1;
        }
        int sock=socket(AF_INET,SOCK_STREAM,0);
        if(sock<0)
        {
                printf("Failed to create socket.\n");
                return 1;
        }
        printf("Socket created.\n");
        sockaddr_in srv_addr;
        srv_addr.sin_family=AF_INET;
        srv_addr.sin_port=htons(8908);
        hostent *server=gethostbyname(argv[1]);
        if(!server)
        {
                printf("Can't resolve: %s\n",argv[1]);
                close(sock);
                return 2;
        }
        strncpy((char*)&srv_addr.sin_addr.s_addr,(char*)server->h_addr,server->h_length);
        if(connect(sock,(sockaddr*)&srv_addr,sizeof(srv_addr))<0)
        {
                printf("Connection failed.\n");
                perror();
                close(sock);
                return 3;
        }
        printf("Connected.\n");
        char *buf=new char[200];
        printf("Enter message:\n");
        fgets(buf,200,stdin);
        if(send(sock,buf,200,0)<0)
        {
                printf("Send error.\n");
                close(sock);
                return 4;
        }

        delete[] buf;
        close(sock);
        return 0;
}



srv.cpp:
Код

#include <cstdio>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <cstring>

int main(int argc, char **argv)
{
        int lsock=socket(AF_INET,SOCK_STREAM,0);
        if(lsock<0)
        {
                printf("Failed create socket.\n");
                return 1;
        }
        printf("Socket created.\n");
        sockaddr_in srv_addr;
        srv_addr.sin_family=AF_INET;
        srv_addr.sin_port=htons(8908);
        srv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
        //hostent *srvhost=gethostbyname("127.0.0.1");
        //strncpy((char*)&srv_addr.sin_addr.s_addr,(char*)srvhost->h_addr,srvhost->h_length);
        if(bind(lsock,(const sockaddr*)&srv_addr,sizeof(srv_addr))<0)
        {
                printf("Bind error.\n");
                return 2;
        }
        printf("Socket binded. Listening...\n");
        int res=listen(lsock,0);
        if(res<0)
        {
                printf("Listen failed.\n");
                close(lsock);
                return 3;
        }
        printf("Listen success. Accepting...\n");
        sockaddr_in cli_addr;
        socklen_t cli_addr_size=sizeof(cli_addr);
        int commSock=accept(lsock,(sockaddr*)&cli_addr,&cli_addr_size);
        if(commSock<0)
        {
                printf("Accept failed.\n");
                close(lsock);
                return 5;
        }
        printf("Connection accepted.\n");

        char *buf=new char[200];
        if(recv(commSock,buf,200,0)<0)
        {
                printf("Recv error.\n");
                close(commSock);close(lsock);
        }
        printf("Message: %s\n",buf);

        delete[] buf;
        close(commSock);
        close(lsock);

        return 0;
}



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

Теперь если в сервере закомментировать строку 20 и раскомментировать 21-22, то он запуститься без ошибок и начнет слушать, но клиент так же не будет поключатся.

Если вместо INADDR_ANY написать INADDR_LOOPBACK, то сервер так же запускается, а клиент не подключается.

Во всех случаях клиент выводит:
Connection failed.
Network is unreachable

Пинги до локалхоста ходят нормально.

Как эта сеть может быть недоступна? В чем проблема?

Информация о системе:
Код

user@linux:~/workspace/sock> /sbin/ifconfig 
eth0      Link encap:Ethernet  HWaddr 6C:F0:48:B7:2С:56  
          inet addr:<внешний адрес>  Bcast:<бкаст внешнего адреса>  Mask:255.255.255.224
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:117565 errors:0 dropped:0 overruns:0 frame:0
          TX packets:96306 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:119076272 (113.5 Mb)  TX bytes:15126608 (14.4 Mb)
          Interrupt:34 Base address:0x2000 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:4629 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4629 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:2654823 (2.5 Mb)  TX bytes:2654823 (2.5 Mb)

user@linux:~/workspace/sock> uname -a
Linux linux 2.6.34.7-0.3-desktop #1 SMP PREEMPT 2010-09-20 15:27:38 +0200 x86_64 x86_64 x86_64 GNU/Linux
user@linux:~/workspace/sock>



Это сообщение отредактировал(а) VirtualVoid - 1.10.2010, 19:53
PM MAIL ICQ   Вверх
Олег2005
Дата 4.10.2010, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

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



На клиенте
gethostbyname(argv[1]) - argv[1] - должен быть localhost

 int res=listen(lsock,0);
Грубая ошибка.
Очередь запросов на соединение равна нулю
Укажите 
 int res=listen(lsock,5);
PM MAIL WWW MSN   Вверх
VirtualVoid
Дата 7.10.2010, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(Олег2005 @  5.10.2010,  03:46 Найти цитируемый пост)
 int res=listen(lsock,0);
Грубая ошибка.

Понял, исправлю. Хотя с одним клиентом и так работало.

Основная же проблема решилась упорным вчитыванием в ман. Там написано, что очень много функций, относящихся к сокетам, объявлены deprecated и obsolete, и вместо gethostbyname надо использовать getaddrinfo.

Функция gethostbyname в моей системе работала вобще некорректно и на имя localhost возвращала IP-адрес 127.0.0.0
getaddrinfo возвращает 127.0.0.1, программа работает правильно.

PM MAIL ICQ   Вверх
Олег2005
Дата 7.10.2010, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

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



Цитата(VirtualVoid @  7.10.2010,  17:55 Найти цитируемый пост)
Функция gethostbyname в моей системе работала вобще некорректно и на имя localhost возвращала IP-адрес 127.0.0.0

Что это у вас за такая система? smile 
Эта функция - классика DNS - и работает как штык во всех системах. smile 
То что у вас - это просто недоразумение какое-то.......
PM MAIL WWW MSN   Вверх
GrayCardinal
Дата 8.10.2010, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Фигасе
****


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

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



Цитата

Основная же проблема решилась упорным вчитыванием в ман. Там написано, что очень много функций, относящихся к сокетам, объявлены deprecated и obsolete, и вместо gethostbyname надо использовать getaddrinfo.

Пожалуйста, линк в студию :(

Добавлено через 1 минуту и 36 секунд
Во дела. Сидишь на руби и не ведаешь что gethostbyname "deprecated" :( А в новых манах это написано :(


--------------------
PM MAIL WWW   Вверх
Олег2005
Дата 9.10.2010, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

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



Цитата(GrayCardinal @  8.10.2010,  10:15 Найти цитируемый пост)
getaddrinfo

Это действительно более новая функция - и более продвинутая, так как работает как в IPv4 так и в IPv6
Только и всего.....
Но gethostbyname() - никто не отменял.... и все стеки ее поддерживают.....

Это сообщение отредактировал(а) Олег2005 - 9.10.2010, 23:12
PM MAIL WWW MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




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


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

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