Автор Гілка: Програмування сокетів в лінукс.  (Прочитано 4237 раз)

Відсутній Markus

  • Дописувач
  • **
  • дописів: 79
  • Карма: +0/-0
  • Програматор
Привіт усім! Виникла потреба написати свій міні http клієнт, який посилає POST GET запити.
 Принцип роботи:
  1.  відкрив сокет
  2. Поки не оброблю дані
    2.1.  послав запит (POST, GET )
    2.3. Зчитав результат
  3. закрив сокет.

Виникла наступна проблема: послав запит, зчитав результат - а сервер на своїй стороні закрив з'єднання, щоб ще раз послати запит і зчитати дані треба закривати сокет і конектитись знову, чи можна це якось обійти? Curl  тут не підходить, бо він при новому реквесті створює новий сокет-конекшин, а це не добре, через запити створюється повно конекшнів, і в результаті мій клієнт баниться моїм фаєрволом  :(. Може хтось уже із таким стикався, знає рішення? Наперед вдячний за відповіді.

Тут код :
int init_connect(const char* url)
{
  struct addrinfo hints, *addr;
  struct sockaddr_in *addrInfo;
  
  errors = NO_ERROR;
  
  load_host_info(url);
  
  int rc;
  int sock;
      
  memset(&hints, 0, sizeof(hints));
  
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags    = AI_ADDRCONFIG;
  
  if( (rc = getaddrinfo(hostInfo.host, NULL, &hints, &addr)) ) {
    //fprintf(stderr, "Can't find host name: %s, Error:%s\n", hostInfo.host, gai_strerror(rc));
    errors = CANT_FIND_HOSTNAME;
    return 0;
  }
  
    
  addrInfo = (struct sockaddr_in *) addr->ai_addr;
  
  if( (sock = socket(addrInfo->sin_family, addr->ai_socktype, addr->ai_protocol)) < 0 ) {
    //fprintf(stderr, "Can't create socket to host name: %s, Error:%s\n", hostInfo.host, gai_strerror(rc));
    errors = CANT_CRETE_SOCKET;
    return 0;
  }
  
  addrInfo->sin_port= htons(80);
  
  int bOptVal = 1;
  int bOptLen = sizeof(int);  
  setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &bOptVal, bOptLen);
  
  if( connect(sock, (struct sockaddr *) addrInfo, addr->ai_addrlen) ) {
    //fprintf(stderr, "Can't connect to host name: %s, Error:%s\n", hostInfo.host, gai_strerror(rc));
    errors = CANT_CONNECT_TO_HOST;
    return 0;
  }
  
  freeaddrinfo(addr);
  
  return sock;
}

char* connector_get(int socket_fd)
{
  char* header = getHeader();
          
  char* request = (char*)malloc( sizeof(char) * strlen(header) * strlen(hostInfo.host) * 4 * strlen(hostInfo.url));
  
  sprintf( request, header, "GET",hostInfo.url,hostInfo.host);
  
  printf("Request: %s\n", request);
  
  ssize_t number_characters_read;
    
  //write (socket_fd, request, strlen(request));
  send (socket_fd, request, strlen(request),0);
  
  int bufSize = 500;
  
  if( response != NULL ) {
    free(response);
  }
    
  response = malloc( sizeof(char) *(bufSize + 1));
      
  //number_characters_read = read(socket_fd, response, bufSize);
  number_characters_read = recv(socket_fd, response, bufSize,0);
  if( number_characters_read == 0 ) {
    strcpy(response, "EMPTY");
    return response;
  }
  
  response[number_characters_read+1]='\0';
      
  free(request);
  
  return response;
}

char* getHeader()
{
  return "%s %s HTTP/1.1\r\n"
         "Host: %s\r\n"
         "Accept: text/html\r\n"
         "Accept: */*\r\n"
         "Keep-Alive: 300\r\n"
         "Connection: keep-alive\r\n"
         "User-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.0.8) Gecko/2009032600 SUSE/3.0.8-1.1.1 Firefox/3.0.8\r\n\r\n";
      
}
Чи потрібні Україні програмісти, які не знають англійської мови?

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3820
  • Карма: +11/-0
  • Програміст
Re: Програмування сокетів в лінукс.
« Відповідей #1 : 2010-11-15 13:25:04 »
Потрібно використовувати HTTP/1.1 і параметер Keep-Alive. Для методу GET можна також використовувати pipelining (http://www.mozilla.org/projects/netlib/http/pipelining-faq.html), якщо сервер підтримує.

Можна скористатися curl-ом: http://curl.haxx.se/dev/readme-pipelining.html
[Fedora Linux]

Відсутній peinguin

  • Літератор
  • ******
  • дописів: 1419
  • Карма: +0/-0
Re: Програмування сокетів в лінукс.
« Відповідей #2 : 2010-11-17 11:40:47 »
А python не канає?

Відсутній piktor

  • Видавець
  • *******
  • дописів: 3396
  • Карма: +0/-0
Re: Програмування сокетів в лінукс.
« Відповідей #3 : 2010-11-17 18:26:38 »
А python не канає?
До чого тут python? Тут про HTTP розмова.
Всим, хто тоне й не знає,
За що вхопитись,
Хто вже з останніх
Вибився сил:
Попереджаю - я не колода,
Попереджаю - я крокодил.

Відсутній peinguin

  • Літератор
  • ******
  • дописів: 1419
  • Карма: +0/-0
Re: Програмування сокетів в лінукс.
« Відповідей #4 : 2010-11-18 07:40:03 »
Ну якщо мова не має значення, можу показати як на пітоні реалізувать.

Відсутній Markus

  • Дописувач
  • **
  • дописів: 79
  • Карма: +0/-0
  • Програматор
Re: Програмування сокетів в лінукс.
« Відповідей #5 : 2010-11-18 09:43:49 »
Сама програма написана на PHP, точніше вебсервіс. Працює через курл (розширення до PHP) але воно, нажаль, має недоліки, тому що створює забагато конекшинів. Стоїть задача написати власне розширення до ПХП для роботи із http. Хотів через сокети, зіткнувся із описаною проблемою, зараз розглядаю варіант написати розширення використовуючи бібліотеку курла, або дослідити його сирці і реалізувати щось подібне.

to peinguin:
Пітон не підходить, хоча було б цікаво, може щось і використаю. Якщо ваша ласка - поділіться кавалком коду :).
Чи потрібні Україні програмісти, які не знають англійської мови?

Відсутній peinguin

  • Літератор
  • ******
  • дописів: 1419
  • Карма: +0/-0
Re: Програмування сокетів в лінукс.
« Відповідей #6 : 2010-11-18 10:28:40 »
Та немає там особо ніякого коду.
Робиться в 2 рядки.
Підключаєте відповідний модуль і використовуєте готовий клас.
http://www.google.com/search?q=python+http+client&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:unofficial

Чомусь мені здається що власний http клієнт - це велосипед.
А щодо Node.js?

Відсутній Markus

  • Дописувач
  • **
  • дописів: 79
  • Карма: +0/-0
  • Програматор
Re: Програмування сокетів в лінукс.
« Відповідей #7 : 2010-11-18 11:44:42 »
Та немає там особо ніякого коду.
Робиться в 2 рядки.
Підключаєте відповідний модуль і використовуєте готовий клас.
http://www.google.com/search?q=python+http+client&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:unofficial

Чомусь мені здається що власний http клієнт - це велосипед.
А щодо Node.js?
Node - трохи не те, із програма із html не працює, і треба реалізувати отримання даних на рівні пхп. Якщо викрристовувати Zend_Http_Client получається та сама проблема, що й при використанні С сокетів.
Чи потрібні Україні програмісти, які не знають англійської мови?

Відсутній kalina

  • Дописувач
  • **
  • дописів: 57
  • Карма: +0/-0
Re: Програмування сокетів в лінукс.
« Відповідей #8 : 2010-11-18 14:29:57 »
Стоїть задача написати власне розширення до ПХП для роботи із http.

А чим AJAX не влаштовує ?


Відсутній Markus

  • Дописувач
  • **
  • дописів: 79
  • Карма: +0/-0
  • Програматор
Re: Програмування сокетів в лінукс.
« Відповідей #9 : 2010-11-18 16:22:11 »
 :) .Специфіка проекту. Про AJAX  тут і мова йти не може. Готових рішень тут не має, Хіба що існує алтернатива курла.  Я не знаю деталей як саме функціонує проект, мені розказали лише суть щоб я зрозумів що тут робити. А рішення тут одне, написати альтернатив курлу.
Чи потрібні Україні програмісти, які не знають англійської мови?