Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: gethostbyname() всегда возвращает НОЛЬ  (Прочитано 13076 раз)
0 Пользователей и 1 Гость смотрят эту тему.
racner
Гость
« : 13-04-2010 21:51 » 

Всем привет!

Изучаю сокеты в С++, использую MS VS 2008.

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

Вот код:
Код:
#include "stdafx.h" // здесь подключены необходимые библиотеки

using namespace std;

#define MY_ADDR "localhost"
#define PORTNUM 80

int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL, "rus"); //включаем русский текст в консоле

SOCKET s;
sockaddr_in serv_addr;
hostent *hp=NULL;

s = socket(AF_INET,SOCK_STREAM,0);
if(!s)
{
perror("Ошибка вызова socket() "); exit(0);
}

hp = gethostbyname(MY_ADDR);
if(!hp)
{
perror("Ошибка вызова gethostbyname() "); exit(0);
}

serv_addr.sin_family = hp->h_addrtype;
serv_addr.sin_port = htons(PORTNUM);

cout << serv_addr.sin_family << endl
<< serv_addr.sin_port << endl;

connect(s,(sockaddr*)&serv_addr,sizeof(serv_addr));

closesocket(s);

return 0;
}

Компилируется, запускается. В MY_ADDR пробовал адреса разных сайтов, но почему же gethostbyname() всегда возвращает ноль? Выход в Интернет есть. Локальный сервер запущен - localhost.

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

Заранее спасибо за любые мысли =)
« Последнее редактирование: 14-04-2010 04:50 от Sel » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 13-04-2010 22:38 » 

Ну насколько я знаю, в винде, чтоб сокеты начали работать, их сначало нужно проиницилизировать. https://club.shelek.ru/viewart.php?id=35
Цитата
Шаг 2 - инициализация.


Теперь мы можем спокойно использовать функции WinsockAPI. (полный список функций можно найти в соответствующих разделах MSDN).

Для инициализации Winsock вызываем функцию WSAStartup
Код:
int WSAStartup( WORD wVersionRequested, (in) LPWSADATA lpWSAData (out) );

Параметр WORD wVersionRequested - младший байт - версия, старший байт - под.версия, интерфейса Winsock. Возможные версии - 1.0, 1.1, 2.0, 2.2... Для "сборки" этого параметра используем макрос MAKEWORD. Например: MAKEWORD (1, 1) - версия 1.1. Более поздние версии отличаются наличием новых функций и механизмов расширений. Параметр lpWSAData - указатель на структуру WSADATA. При возврате из функции данная структура содержит информацию о проинициализированной нами версии WinsockAPI. В принципе, ёё можно игнорировать, но если кому-то будет интересно что же там внутри - не поленитесь, откройте документацию Ага
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
racner
Гость
« Ответ #2 : 13-04-2010 23:00 » 

Спасибо за ответ, Finch!

Я тоже уже тут нашел, проблема решается, если добавить в начале:

Код:
	WSADATA wsaData;
int err = WSAStartup(MAKEWORD(2, 0), &wsaData);
if (err != 0)
{
perror("Ошибка загрузки библиотеки "); exit(0);
}

Ага, перед тем как использовать библиотеку winsock, её нужно загрузить функцией WSAStartup().

Везде в сети имеется статья Танаева по использованию сокетов. Там нет инициализации библиотеки (статья для Unix написана, выходит?), и этим вводит в заблуждение.

И кстати, там есть функции bzero и bcopy - что сделать, чтобы их вызывать в Visual C++  непонятно. В msdn их, похоже, нет. Вместо bzero - ZeroMemory, а вместо bcopy тогда что?
« Последнее редактирование: 14-04-2010 04:47 от Sel » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 14-04-2010 05:11 » 

racner, memset, memmove. memcpy
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 29-07-2010 07:31 » 

А вот такой глупый вопрос. Как определить, сколько байтов в очереди приёма, не считывая эти байты?

вызов
recv(..., MSG_PEEK)

требует указания буфера, то есть будет чтение. От этого отговаривают и тут
http://support.microsoft.com/kb/q140263/

То есть, нельзя, получается, не читая, определить, сколько там байтов накопилось ?
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 29-07-2010 09:43 » 

Чтение то будет, но данные в буфере не удаляются.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 29-07-2010 10:03 » 

Но получится чтение два раза ведь.

А хочется просто количество узнать
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 29-07-2010 10:57 » 

Ты же в винде это делаешь - посмотри в MSDN winsock2, может там какие-нибудь фишки есть.

Вот только не пойму, зачем тебе такое? Просто даешь буфер заведомо больший и получаешь в ответ фактическое количество байтов. Держать буфер наполненным - дело нехорошее.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 29-07-2010 11:26 » 

да вроде и нет другого способа. Зачем нужно - у меня шаблонная функция, где в качестве T передаётся ссылка на устройство приёма. А это может быть компорт, USB или сокет. Описал во всех трёх функцию GetFilledSize(), из первых двух нашёл, как правильно вернуть размер уже принятого, а для сокета вернул 0xFFFFFFFF. По этому признаку делается обрезка читаемого блока до приёмного буфера
Записан

Phodopus
Интересующийся

ru
Offline Offline

« Ответ #9 : 17-08-2010 14:20 » 

Цитата: MSDN
FIONREAD
Use to determine the amount of data pending in the network's input buffer that can be read from socket s. The argp parameter points to an unsigned long value in which ioctlsocket stores the result.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 17-08-2010 15:45 » 

Phodopus, о, спасибо )
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines