ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > Программирование > С/С++, C#, Delphi, .NET, Asm
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

C++ функция recv зависает, сокеты, проблема
  #1  
Старый 17.06.2009, 19:06
awdrg
Участник форума
Регистрация: 30.01.2009
Сообщений: 196
Провел на форуме:
505362

Репутация: 66
Отправить сообщение для awdrg с помощью ICQ
По умолчанию C++ функция recv зависает, сокеты, проблема

Пишу в обучающих целях простой граббер web-страниц. Открываю сокет, отсылаю заголовок функцией send. Далее начинается чтение ответа и самого кода странички функцией recv. Тут начинаются проблемы - после чтения предпоследней порции информации функция "переходит в режим ожидания" Флаг MSG_PEEK не помогает. Вопрос: как избежать этого виса, возможно ли поставить recv на таймаут? Приведите пожалуйста простой пример кода с решением.
Пока решаю это проблему так: в каждой порции ответа сервера ищу "\r\n\r\n", если нахожу более 2 раз - выход из цикла приема.
 
Ответить с цитированием

  #2  
Старый 17.06.2009, 19:33
d_x
Reservists Of Antichat - Level 6
Регистрация: 25.03.2008
Сообщений: 670
Провел на форуме:
4137635

Репутация: 2407


По умолчанию

Когда я с помощью send-recv работал с вебом, таких проблем не было. Просто я проверял, сколько байт считано (это и возвращает recv), и если это число равно 0, то цикл чтения закончен. Простой пример кода только на асме могу привести, на нем и писал)
Лучше бы показал свой код.
 
Ответить с цитированием

  #3  
Старый 17.06.2009, 19:55
razb
Постоянный
Регистрация: 24.03.2009
Сообщений: 670
Провел на форуме:
2868783

Репутация: 414


Отправить сообщение для razb с помощью ICQ
По умолчанию

Цитата:
C++ функция recv зависает, сокеты, проблема
Покажи свой код, тут не телепаты...
 
Ответить с цитированием

  #4  
Старый 17.06.2009, 20:01
awdrg
Участник форума
Регистрация: 30.01.2009
Сообщений: 196
Провел на форуме:
505362

Репутация: 66
Отправить сообщение для awdrg с помощью ICQ
По умолчанию

Я так и пытался делать. Проблема в том, что если размер буфера чуть больше кол-ва оставшихся байт то он пытается что то читать (около минуты функция висит)
вот кусок кода
PHP код:
#define PORT 80
#define SERVERADDR "forum.antichat.ru" 
char connect()
{
   
WSADATA wd;
   
char buff[256] = "\0";
   
char text[100000] = "\0";
   
char buff2[10000]="GET / HTTP/1.1\r\nHost: forum.antichat.ru\r\nUser-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.0.11) Gecko/2009060308 Ubuntu/9.04 (jaunty) Firefox/3.0.11\r\nAccept-Language: ru,en-us;q=0.7,en;q=0.3\r\nKeep-Alive: 300\r\nConnection: keep-alive\r\n\r\n";
   
printf "TCP Client \n" );
   if ( 
WSAStartup 0x202, &wd ) )
   {
      return 
"[Connection error]";
   }

   
SOCKET sock ;
   
sock=socket AF_INETSOCK_STREAM);
   if  ( 
sock )
   {
       return  
"[Socket error]";
   }

   
sockaddr_in  dest_addr;
   
dest_addr.sin_family=AF_INET;
   
dest_addr.sin_port=htons PORT );
   
HOSTENT    *hst;
   if( 
inet_addr(SERVERADDR) != INADDR_NONE )
       
dest_addr.sin_addr.S_un.S_addr inet_addr(SERVERADDR);
   else if( 
hst=gethostbyname SERVERADDR ) )
       ( ( 
unsigned long   * ) &dest_addr.sin_addr )[0]=((unsigned long** )hst->h_addr_list)[0][0];
   else
   {
      
closesocketsock ) ;
      
WSACleanup();
      return  
"[Bad address]";
   }

   if(
connectsock, (sockaddr *)&dest_addrsizeof(dest_addr) ))
   {
      return 
"[Connection error]";
   }

   
sendsockbuff2strlen(buff2), 0);
   
int x 1;
   
FILE ff fopen("log.txt","w");
   while (
x>0)
   {
      
recvsockbuff256); // 256 - buffer size
      
strcat(text,buff);
      
fputs(buff,ff);
   }
   
fclose(ff);
   return 
text;


Последний раз редактировалось awdrg; 17.06.2009 в 20:07..
 
Ответить с цитированием

  #5  
Старый 17.06.2009, 21:20
d_x
Reservists Of Antichat - Level 6
Регистрация: 25.03.2008
Сообщений: 670
Провел на форуме:
4137635

Репутация: 2407


По умолчанию

Как вариант - использовать не keep-alive соединение, а close. Протокол надо использовать HTTP/1.0, а не 1.1, иначе придется парсить содержимое, так как сервер может отсылать его в этом случае кусками с Transfer-Encoding: chunked. Кстати, в файл надо писать не просто строку buff с помощью fputs, так как последний байт у нее необязательно нулевой, а следует использовать fwrite и явно указывать размер записываемого буфера.
Примерно так:
PHP код:
 #define PORT 80 
#define SERVERADDR "forum.antichat.ru" 


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

int myconnect() 

   
WSADATA wd
   
char buff[256] = {0}; 
   
char *buff2="GET / HTTP/1.0\r\nHost: forum.antichat.ru\r\nUser-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.0.11) Gecko/2009060308 Ubuntu/9.04 (jaunty) Firefox/3.0.11\r\nAccept-Language: ru,en-us;q=0.7,en;q=0.3\r\nConnection: close\r\nContent-length: 0\r\n\r\n\n"
   
printf "TCP Client \n" ); 
   if ( 
WSAStartup 0x0101, &wd ) ) 
   { 
      return 
0
   } 

   
SOCKET sock 
   
sock=socket AF_INETSOCK_STREAM); 
   if  ( 
sock 
   { 
       return  
0
   } 

   
sockaddr_in  dest_addr
   
dest_addr.sin_family=AF_INET
   
dest_addr.sin_port=htons PORT ); 
   
HOSTENT    *hst
   if( 
inet_addr(SERVERADDR) != INADDR_NONE 
       
dest_addr.sin_addr.S_un.S_addr inet_addr(SERVERADDR); 
   else if( 
hst=gethostbyname SERVERADDR ) ) 
       ( ( 
unsigned long   * ) &dest_addr.sin_addr )[0]=((unsigned long** )hst->h_addr_list)[0][0]; 
   else 
   { 
      
closesocketsock ) ; 
      
WSACleanup(); 
      return  
0
   } 

   if(
connectsock, (sockaddr *)&dest_addrsizeof(dest_addr) )) 
   { 
      return 
0
   } 

   
sendsockbuff2strlen(buff2)-10); 
   
int x 255
   
FILE ff fopen("log.txt","w"); 
   while (
x>0
   { 
      
recvsockbuff255); // 256 - buffer size

      
printf("Got %u bytes\n",x);
      
fwrite(buff,1,x,ff); 
   } 
   
printf("finished\n",x);
   
closesocketsock ) ; 
   
WSACleanup(); 
   
fclose(ff); 
   return 
1
}  

int main()
{
 
myconnect();
 return 
0;   


Последний раз редактировалось d_x; 17.06.2009 в 21:25..
 
Ответить с цитированием

  #6  
Старый 17.06.2009, 21:58
awdrg
Участник форума
Регистрация: 30.01.2009
Сообщений: 196
Провел на форуме:
505362

Репутация: 66
Отправить сообщение для awdrg с помощью ICQ
По умолчанию

Цитата:
Сообщение от d_x  
Как вариант - использовать не keep-alive соединение, а close. Протокол надо использовать HTTP/1.0, а не 1.1
Хм, проблема так просто решилась, большое спасибо!
 
Ответить с цитированием

  #7  
Старый 18.06.2009, 00:18
slesh
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме:
3288241

Репутация: 3349


Отправить сообщение для slesh с помощью ICQ
По умолчанию

а на счет таймаута для recv в моей статейке почитай
 
Ответить с цитированием

  #8  
Старый 18.06.2009, 09:30
_Great_
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме:
5339610

Репутация: 4360


Отправить сообщение для _Great_ с помощью ICQ
По умолчанию

Content-Length!
 
Ответить с цитированием

  #9  
Старый 18.06.2009, 09:52
slesh
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме:
3288241

Репутация: 3349


Отправить сообщение для slesh с помощью ICQ
По умолчанию

2 _Great_ а если сервак еб*н*тый и непосылает Content-Length - тогда облом. )
 
Ответить с цитированием

  #10  
Старый 18.06.2009, 15:35
_Great_
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме:
5339610

Репутация: 4360


Отправить сообщение для _Great_ с помощью ICQ
По умолчанию

При кипелайв соединении обязан. Иначе браузер никогда не узнает когда посылать запрос очередной.
А при клоуз - оно и не нужно.
 
Ответить с цитированием
Ответ



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Бот для техномагии Rastamanka Реверсинг 13 08.06.2010 06:06
Joker Board Comerv 2.0 SXtingeR13 PHP, PERL, MySQL, JavaScript 4 16.01.2010 09:48
Криптографический Словарь bobob Чужие Статьи 5 15.08.2006 00:51



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ