winsock прием данных

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Spy2ex, 21 Oct 2010.

  1. Spy2ex

    Spy2ex Elder - Старейшина

    Joined:
    20 Sep 2008
    Messages:
    32
    Likes Received:
    15
    Reputations:
    1
    Посылаю запрос на свой сервер через прокси.

    Code:
    POST domen.ru/index.php HTTP/1.1  
    Host: domen.ru  
    Content-Length: 19  
    Content-type: application/x-www-form-urlencoded  Referer: http://site.com  
    Cookie: sole=11123  
    X-Proxy-ID: 1635563617  
    X-Forwarded-For: 1111  
    Via:  (Mikrotik HttpProxy)    
    
    post_data=123443123
    
    код приема сервера
    Code:
    do
    	{
               recv_res = recv(sock, tempBuffer, 1023,0);
               switch(recv_res)
    		   {
    			   case -1 : // error
    			   break;
    
    			   case 0: // close conn
    			   break;
    		   }
    
    
       } while(recv_res>0);
    
    Когда данные от клиента передаются на прокси сервер (имею ввиду POST), прокси обрезает их тело запроса и сами пост данные.

    Когда данные приходят на мой сервер (с прокси)я их анализирую и отправляю ответ.

    Вот листинг сниффера что приходит мне на сервер:
    Code:
    POST /index.php HTTP/1.1
    Host: domain.ru
    Content-Length: 19
    Content-type: application/x-www-form-urlencoded
    Referer: http://site.com
    Cookie: sole=11123
    X-Proxy-ID: 1635563617
    X-Forwarded-For: 11111
    Via: 1.1 11111 (Mikrotik HttpProxy)
    
    ------------- мой ответ сервака
    HTTP/1.0 200 OK
    Content-Type: text/html
    Content-Length: 44
    ------------------------------------------
    post_data=123443123 - пост данные которые я должен принять до ответа моего сервака
    
    Как видно мой сервер не успевает все принять а сразу шлет ответ.

    Картинка для наглядности:
    [​IMG]

    В некоторых случаях мне удается правильно принять данные при таком же раскладе.
    Вопрос, как правильно написать прием данных, в таком случаи которые я описал.
     
    #1 Spy2ex, 21 Oct 2010
    Last edited: 21 Oct 2010
  2. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    а счего это ты посылаешь POST site.com ??
    POST http://site.com/.... надо же
    Я тебе уже 100 раз говорил что прокси может разбить на части запрос.
    Ты скорее всего считал первую часть, затем ответил на неё а потом считал вторую часть. так что или показывай целеком код или хз
     
    1 person likes this.
  3. Spy2ex

    Spy2ex Elder - Старейшина

    Joined:
    20 Sep 2008
    Messages:
    32
    Likes Received:
    15
    Reputations:
    1
    Code:
    
     "POST http://site.ru/index.php HTTP/1.1\r\n"
     "User-Agent: Mozilla/5.0\r\n"
     "Referer: http://example.org\r\n"
     "Cookie: simple=justtotalityletters\r\n"
     "Content-Length: 35\r\n"
     "Content-Type: application/x-www-form-urlencoded\r\n"
     "Connection: сlose\r\n\r\n"
    
     "post_data=someverylongrequeststring";
    
    Запрос клиента к проксе.

    код сервера:
    Code:
    string sBuff =
    "HTTP/1.0 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Content-Length: 44\r\n\r\n";
    
    string recv_data (SOCKET sock)
    {
    	string result;
    	char tempBuffer[1024];
    	int recv_res;
        ZeroMemory(&tempBuffer, sizeof(tempBuffer));
    	DWORD recv_timeout2 = 6*1000;
    	setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&recv_timeout2, sizeof(DWORD));
    	do
    	{
               recv_res = recv(sock, tempBuffer, 1023,0);
               switch(recv_res)
    		   {
    			   case -1 :
    			   break;
    
    			   case 0:
    			   break;
    		   }
       } while(recv_res>0);
       result = tempBuffer;
       return result.c_str();
    }
    
    unsigned __stdcall client_thread(void * param)
    {
    SOCKET s = (SOCKET) param;
    string r = recv_data(s);
    // инализируем строку
    
    send(s,sBuff.c_str(),sBuff.length(),0);
    
    closesocket(s);
    return 0;
    }
    
    int main ()
    {
    // инициализация ......
       for(;;)
       {
                sockAcc = accept(sockServ, 0, 0); 
    
    	unsigned ret;
    	_beginthreadex(0,0,client_thread,(void*)sockAcc,0,&ret);
        }
    
    return 0;
    }
    
    Проверок нету

    p.s Я понял что прокси разбивает запрос на части, но как мне их правильно считать=)
     
  4. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    Code:
    do
    	{
               recv_res = recv(sock, tempBuffer, 1023,0);
               switch(recv_res)
    		   {
    			   case -1 :
    			   break;
    
    			   case 0:
    			   break;
    		   }
       } while(recv_res>0);
    
    
    Странно что это вообще пашет. Ты получается всегда в буфере будешь иметь последний пакет. первый раз считал, а при втором чтении ты затрешь предыдущии данные. ДА и код просто пздц дохера лишних проверок

    Прощe былобы уже
    Code:
    xxxxxx <--- обнуляешь свою строку которую возвращаешь. вернее инициализируешь пустую строку
    for (;;)
    {
          recv_res = recv(sock, tempBuffer, 1023,0);
          if (recv_res > 0)
          {
                tempBuffer[recv_res] = 0; // если работаешь со строками, то необходимо в конце данных ставить символ конца строки
                xxxxxxxxxx <--- а вот тут вот ты уже добавляешь считанные данные к своей строке
          }
          else break;
    }
    
    
     
  5. Spy2ex

    Spy2ex Elder - Старейшина

    Joined:
    20 Sep 2008
    Messages:
    32
    Likes Received:
    15
    Reputations:
    1
    Спасибо помогло, исправил функцию приема данных и все заработало.