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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ограничение на количество открытых сокетов 
:(
    Опции темы
alltouch
Дата 7.6.2006, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Мне нужно загрузить прогой много страниц(примерно 1000)
1. Какое ограничение на количество открытых сокетов существует в винде и линухе???
2. Я гружу каждую страницу в отдельном потоке (в винде с помощью библиотеки winsock, под линухом - обычными сокетами), когда поток работает больше 5 секунд я его вырубаю. Закрывается при этом сокет или нет?? если нет то как ево закрыть в этом случае??????? 
PM MAIL   Вверх
Dian
Дата 7.6.2006, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Закрывается через closesocket;
Адресное пространство портов 0001-FFFF, скорее всего реальный предел будет  меньше, но на пару тысяч хватит
 
PM MAIL WWW   Вверх
alltouch
Дата 13.6.2006, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



а все таки можно какую-то примерную цыфру ограничения на количество одновременно открытых сокетов узнать???? 
PM MAIL   Вверх
deniska
Дата 13.6.2006, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



так возьми проверь. если у тебя уже есть код для открывания 1000 страниц открой 2, 3, 4 тысячи пока все не грохнется smile  я думаю число сокетов ограничено 
Цитата

0001-FFFF
 и свободными ресурсами системы (в винде по крайней мере) с линухом не знаком 
PM MAIL ICQ   Вверх
p0s0l
Дата 13.6.2006, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

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



Загляни сюда:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
Здесь есть такие параметры:
TcpTimedWaitDelay - время, когда соединение после разрыва находится в состоянии TIME_WAIT. В это время нельзя снова установить соединение между этой же парой сокетов. Имеет значение, если очень часто открываешь-закрываешь соединения с одними и теми же хостами.

TcpNumConnections - макс. количество одновременно открытых TCP соединений. По умолчанию ограничение 16 млн с копейками.

MaxUserPort - максимально доступный открываемый № порта, по умолчанию 5000. 

Если у тебя грузится всего 1000 страниц, то этих ограничений должно по идее хватить с запасом... 

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

Ссылки:
http://support.microsoft.com/kb/314053/
http://support.microsoft.com/?id=196271
 


--------------------
С уважением, г-н Посол.
PM   Вверх
alltouch
Дата 13.6.2006, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



У меня такая вот проблема, когда я гружу страницы через сокеты, то через определенное время(скоре всего после n-того открытого сокета) все остальные сокеты просто висят(в моем случае оставалось открытых пару штук) и сами завершаться не хотят, что в этом случае делать???? 
PM MAIL   Вверх
ptr
Дата 18.6.2006, 08:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Для закрытия активного соединения используются две функции shutdown и closesocket. closesocket - экстренное закрытие сокета, при этом соединение разрывается сразу. После вызова closesocket сокет будет уже недоступен. Чтобы корректно инициировать закрытие сокета, нужно вызвать shutdown, а потом closesocket. При этом будут переданы все неотправленные данные и получены еще не принятые данные и сокет не будет висеть. 


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
alltouch
Дата 21.6.2006, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Не все так просто, сокеты я открываю в потоках, если поток успевает завершится за 5 секунд тогда сокет сам закрывается, если же нет, то я снимаю поток, при этом в деструкторе сокета прописано чтоб он его сам завершал автоматически...
Но это не помогает бо все равно потом прога висит, чего-то ждет, чего именно я пока не знаю 
PM MAIL   Вверх
ptr
Дата 21.6.2006, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Так у тебя прога висит или сокеты? Кстати неплохо было бы видеть текст проги. 


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
alltouch
Дата 22.6.2006, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



скорее всего высят сокеты, бо прога ничего не делает пока не завершаться все сокеты

P.S. Код очень большой, какой кусок имеено выложить????? 
PM MAIL   Вверх
ptr
Дата 22.6.2006, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Лучше всего конечно весь, но если он такой большой, то ту часть, в которой непосредственно с сокетами работаешь.

И долго твоя прога висит? Может просто она закрывает все открытые сокеты (ты же не один и не два сокета открываешь). 

Это сообщение отредактировал(а) ptr - 22.6.2006, 11:23


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
alltouch
Дата 23.6.2006, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Каждый сокет открывается в отдельном потоке, диспечер пзадач показывал что в моей проге было запущено 4 потока(2 главных и два на сокетах)!!!

Вот мой класс для работы с сокетами:
Код

    class a_socket //объявление класса
    {
        public:
            a_socket(string needle_method, string needle_url, bool use_proxy, string proxy);
            ~a_socket();
            string get_content();
            int get_socket_data();
        private:
            string host, port, page, method, content, proxy_ip, proxy_port;
            bool is_set_proxy;
#ifdef WINDOWS
            SOCKET sock;  //Об"являем идентификатор сокета
#else
            int sock;     //Об"являем идентификатор сокета
#endif
    };

    a_socket::a_socket(string needle_method, string needle_url, bool use_proxy, string proxy) //конструктор
    {
        method=needle_method;  //needle_method

        string temp_string=needle_url;  //needle_url
        if(temp_string.substr(0,7).compare("http://")==0) temp_string=temp_string.substr(7);
        if(temp_string.find('/')==-1)
        {
            host=temp_string;
            page="/";
        }
        else
        {
            host=temp_string.substr(0,temp_string.find('/'));
            page=temp_string.substr(temp_string.find('/'));
        }
        if(host.find(':')==-1) port="80";
        else 
        {
            port=host.substr(host.find(':')+1);
            if(port.compare("")==0) port="80";
            host=host.substr(0,host.find(':'));
        }
        
        is_set_proxy=use_proxy; //proxy
        if(is_set_proxy)
        {
            if(proxy.find(':')==-1)
            {
                proxy_ip=proxy;
                proxy_port="80";
            }
            else
            {
                proxy_ip=proxy.substr(0,proxy.find(':'));
                proxy_port=proxy.substr(proxy.find(':')+1);
                if(proxy_port.compare("")==0) port="80";
            }
            if(inet_addr(&proxy_ip[0])==-1) is_set_proxy=FALSE;
        }
        
        content=""; //content
    }

    a_socket::~a_socket()
    {
        if(sock)
        {
            shutdown(sock, 0x02);
#ifdef WINDOWS
            closesocket(sock);
#else
            close(sock);
#endif
        }
    }

    string a_socket::get_content()
    {
        return content;
    }

    int a_socket::get_socket_data()
    {
        sockaddr_in server_addr;    // структура для адреса
        string send_text="";
        if(is_set_proxy)
        {
            if( ( server_addr.sin_addr.s_addr =inet_addr(proxy_ip.c_str()))==(-1))  // проверим, возможно host содержит просто ip
            {
                // нет, адрес не есть ip, тогда возможно это dns адрес
                hostent* server_host;
                server_host=gethostbyname(proxy_ip.c_str());
                if(server_host==NULL)
                {
                    return 1;  //ошибка, не возможно определить айпи-адрес сайта
                }
                memcpy(&server_addr.sin_addr.s_addr, server_host->h_addr_list[0], server_host->h_length);  //присваиваем айпишник
            }
            server_addr.sin_family = AF_INET;  //указываем что будем использовать айпишники
            server_addr.sin_port =  htons(atoi(proxy_port.c_str()));   //переводим порт в правильный вид
            if((sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)   //создаем сокет
            {
                return 2;   //ошибка, не возможно приконектиться
            }
            if( connect( sock, (sockaddr *)&server_addr, sizeof(server_addr)) != 0)  //соединяемся
            {
                return 3;  //ошибка, не возможно соединиться с хостом
            }  
            send_text=method+" http://"+host+page+" HTTP/1.0\r\n"+
                     +"Host: "+host+"\r\n"+
                     +"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1\r\n"+
                     +"Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n"+
                     +"Accept-Language: en-us,en;q=0.8\r\n"+
                     +"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"+
                     +"Referer: http://"+host+"\r\n"+
                     +"Connection: close\r\n\r\n";
        }
        else
        {
            if( ( server_addr.sin_addr.s_addr =inet_addr(host.c_str()))==(-1))  // проверим, возможно host содержит просто ip
            {
                // нет, адрес не есть ip, тогда возможно это dns адрес
                hostent* server_host;
                server_host=gethostbyname(host.c_str());
                if(server_host==NULL)
                {
                    return 1;  //ошибка, не возможно определить айпи-адрес сайта
                }
                memcpy(&server_addr.sin_addr.s_addr, server_host->h_addr_list[0], server_host->h_length);  //присваиваем айпишник
            }
            server_addr.sin_family = AF_INET;  //указываем что будм использовать айпишники
            server_addr.sin_port =  htons(atoi(port.c_str()));   //переводим порт в правильный вид
            if((sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)   //создаем сокет
            {
                return 2;   //ошибка, не возможно приконектиться
            }
            if( connect( sock, (sockaddr *)&server_addr, sizeof(server_addr)) != 0)  //соединяемся
            {
                return 3;  //ошибка, не возможно соединиться с хостом
            }
            send_text=method+" "+page+" HTTP/1.0\r\n"+
                     +"Host: "+host+"\r\n"+
                     +"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1\r\n"+
                     +"Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n"+
                     +"Accept-Language: en-us,en;q=0.8\r\n"+
                     +"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"+
                     +"Referer: http://"+host+"\r\n"+
                     +"Connection: close\r\n\r\n";
        }
        send(sock, send_text.c_str(), send_text.length(), 0);  //посылаем запрос
        char receive_buf[DEF_BUF_SIZE+5];   //буфер для приема
        int receive_buf_len = recv(sock, receive_buf, DEF_BUF_SIZE, 0);
        while(receive_buf_len>0)
        {
            receive_buf[receive_buf_len]='\0';
            content.append(receive_buf);
            receive_buf_len = recv( sock, receive_buf, DEF_BUF_SIZE, 0);
        }
        shutdown(sock, 0x02);
#ifdef WINDOWS
        closesocket(sock);
#else
        close(sock);
#endif
        return 0;
    }


Использую я его потом так:
Код

a_socket sock("GET",url, use_proxy, proxy);    
sock.get_socket_data();
string page=sock.get_content();

 
PM MAIL   Вверх
ptr
Дата 23.6.2006, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



1. Ты пытаешься два раза закрыть сокет. Первый раз в конце get_socket_data(), второй раз в деструкторе. Тогда в get_socket_data нужно ещё делать sock=0.
Допустим в твоём коде:

a_socket sock("GET",url, use_proxy, proxy);     
sock.get_socket_data(); 
string page=sock.get_content(); 

всё отработало правильно, тогда в get_socket_data() вызовется close (closesocket)+shutdown, а потом в деструкторе ещё раз вызовется close (closesocket), поскольку будет sock!=0.

2. Зачем вообще нужно два раза закрывать сокет. Закрывай его либо в самой функции, либо в деструкторе.

Ну это, пожалуй на первый взгляд, и всё.   

Это сообщение отредактировал(а) ptr - 24.6.2006, 09:29


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




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


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

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