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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> определение ip клиента. проблема с использованием getpeername() 
V
    Опции темы
Lorido
Дата 12.8.2009, 02:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Задача ставилась определить ip подключившегося сокета клиента.
Нашёл пример использования, скокпипастил smile  Однако выдаёт совсем не те адреса при тестовом прогоне. Тыкните пальцем где неточность.
Код

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>    
#include <iostream>    
#include <arpa/inet.h>

int main(){
   int sock_fd;
   int newsock_fd;
   struct sockaddr_in addr;
   struct sockaddr_in ss;
   struct sockaddr_in new_socket;
   unsigned int len;
   unsigned int addr_len;

   sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

   addr.sin_family = AF_INET;
   addr.sin_addr.s_addr = htonl(INADDR_ANY);
   addr.sin_port = htons(15000);
   bind(sock_fd,(struct sockaddr*)&addr,sizeof(addr));
   listen(sock_fd,1);
   newsock_fd = accept(sock_fd,(struct sockaddr*)&new_socket,&addr_len); // Code blocks here

   // Assuming client has connected to the server.
   len = sizeof(ss);
   getpeername(sock_fd,(struct sockaddr*)&ss,&len);
   printf(inet_ntoa(ss.sin_addr));
   close(newsock_fd);
   close(sock_fd);
}



Заранее благодарю.
PM MAIL   Вверх
volkrey
Дата 12.8.2009, 06:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



посмотри, вот в этой строчке (возможно я и ошибаюсь) должен быть дескриптор нового сокета

getpeername(newsock_fd,(struct sockaddr*)&ss,&len);
PM MAIL   Вверх
bourne
Дата 12.8.2009, 06:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Lorido, немного переделал твой сорец:
Код

#include <stdio.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

int main(){
   int sock_fd;
   int newsock_fd;
   struct sockaddr_in addr;
   struct sockaddr_in ss;
   struct sockaddr_in new_socket;
   unsigned int len;
   int addr_len;
   WSADATA WSAData;

    if(WSAStartup (MAKEWORD(1, 1), &WSAData) != 0)
        printf("WsaStartup: %d\n", GetLastError());

    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(7000);
   
    sock_fd = socket(AF_INET, SOCK_STREAM, 0);
    if(sock_fd == -1)
        printf("socket_error: %d\n", GetLastError());

    if(bind(sock_fd,(struct sockaddr*)&addr,sizeof(struct sockaddr_in)) == -1)
        printf("bind_error: %d\n", GetLastError());

    if(listen(sock_fd,1) == -1)
        printf("listen_error: %d\n", GetLastError());

    addr_len = sizeof(struct sockaddr_in);
    newsock_fd = accept(sock_fd,(struct sockaddr*)&new_socket,&addr_len); // Code blocks here

   // Assuming client has connected to the server.
   len = sizeof(ss);

   getpeername(newsock_fd,(struct sockaddr*)&ss,&len);
   printf(inet_ntoa(ss.sin_addr));
   close(newsock_fd);
   close(sock_fd);
}

PM MAIL   Вверх
Lorido
Дата 12.8.2009, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Нет, всё не то. Второй вариант не подходит ввиду того, что это должно стоять на линукс сервере. А подключать при этом виндовую библиотеку не эстетично что ли.
Программа, код которой я скинул, возвращает айпи. Единственно что это не те айпи-адреса с которых проходит тест. Может есть вариант как получить адрес клиента каким нибудь другим способом?

поставил проверку
Код

if(getpeername(sock_fd,(struct sockaddr*)&ss,&len) == -1){
        printf("error");
}


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

Это сообщение отредактировал(а) Lorido - 12.8.2009, 12:56
PM MAIL   Вверх
andrew_121
Дата 12.8.2009, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

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



Lorido, Измени пару строк, и будет работать на Линукс.


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Lorido
Дата 12.8.2009, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



какие строки надо переделать?
меня больше интересует почему
Код

if(getpeername(sock_fd,(struct sockaddr*)&ss,&len) == -1){
        printf("error");
}

выкидывает ошибку.
PM MAIL   Вверх
GoldFinch
Дата 12.8.2009, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



а что не boost::asio?
PM MAIL ICQ   Вверх
Lorido
Дата 12.8.2009, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



ошибка нашлась
оказывается дейтсвительно в примере была ошибка.
Код

if(getpeername([color=red]newsock_fd[/color],(struct sockaddr*)&ss,&len) == -1){
        printf("error");
}

Проморгал. Вот что значит нехватка опыта. Спасибо всем кто помог.
PM MAIL   Вверх
andrew_121
Дата 12.8.2009, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

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



Lorido, Вот:
Код


#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(){
   int sock_fd;
   int newsock_fd;
   struct sockaddr_in addr;
   struct sockaddr_in ss;
   struct sockaddr_in new_socket;
   unsigned int len;
   int addr_len;

    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(7000);
   
    sock_fd = socket(AF_INET, SOCK_STREAM, 0);
    if(sock_fd == -1)
        printf("socket_error: %s\n", strerror(errno));
    if(bind(sock_fd,(struct sockaddr*)&addr,sizeof(struct sockaddr_in)) == -1)
        printf("bind_error: %s\n", strerror(errno));
    if(listen(sock_fd,1) == -1)
        printf("listen_error: %s\n", strerror(errno));
    addr_len = sizeof(struct sockaddr_in);
    newsock_fd = accept(sock_fd,(struct sockaddr*)&new_socket,&addr_len); // Code blocks here
   // Assuming client has connected to the server.
   len = sizeof(ss);
   getpeername(newsock_fd,(struct sockaddr*)&ss,&len);
   printf("%d\n", inet_ntoa(ss.sin_addr));
   close(newsock_fd);
   close(sock_fd);
    
    return 0;
}

И еще: http://www.rsdn.ru/article/unix/sockets.xml настоятельно рекомендую.


Цитата(GoldFinch @  12.8.2009,  15:01 Найти цитируемый пост)
а что не boost::asio? 

Мне тоже интересно.


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
GoldFinch
Дата 12.8.2009, 15:11 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Код

#include <boost/asio.hpp>

int main()
{
        const unsigned short port = 15000;
        try
        {
                boost::asio::io_service io;
                boost::asio::ip::tcp::acceptor acceptor(io,
                        boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4(),port) );
                boost::asio::ip::tcp::socket s(io);
                acceptor.accept(s);
                std::cout << s.remote_endpoint() << std::endl;
        }
        catch (std::exception& e)
        {
                std::cerr << e.what() << std::endl;
                return 1;
        }
        return 0;
}

как-то так

Это сообщение отредактировал(а) GoldFinch - 12.8.2009, 15:13
PM MAIL ICQ   Вверх
andrew_121
Дата 12.8.2009, 15:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

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



GoldFinch, Красотища!


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Олег2005
Дата 12.8.2009, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Небольшой коммент:

listen(sock_fd,backlog)

На самом деле во многих TCP-модулях различных ОС истинное значение длины очереди буфера для приема входящих соединений расчитывается по формуле: 
                                                               backlog * 3 / 2 + 1
и listen(sd, 0) разрешит принять одно соединение,  listen (sd, 5)  - 8. 

Потому значение backlog=1 практически не используют.........

PM MAIL WWW MSN   Вверх
xvr
Дата 13.8.2009, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Кстати, после 
Код

 newsock_fd = accept(sock_fd,(struct sockaddr*)&new_socket,&addr_len); 
в new_socket УЖЕ лежит адрес подключившегося клиента. Нафига еще getpeername звать?

PM MAIL   Вверх
xrays777
Дата 13.8.2009, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



inet_ntoa()
ntohs()


воспользуйся этими функциями и будет тебе счастье
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

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

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

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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