Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[Winsock] Komunikacja z HTTP - powtórne użycie funkcji send()

Ostatnio zmodyfikowano 2013-05-29 22:35
Autor Wiadomość
matthias
Temat założony przez niniejszego użytkownika
[Winsock] Komunikacja z HTTP - powtórne użycie funkcji send()
» 2013-05-05 18:20:57
Witam,
Przegrzebałem google wzdłuż i wszerz (jak i również to forum) i nie znalazłem podobnego problemu do mojego.
Otóż, postanowiłem wykonać coś ala automat do ankiet na stronie internetowej, który by łączył się poprzez proxy, pobierał źródło strony za pomocą GET, wygrzebywał potrzebne dane z formularza i odsyłał wszystko za pomocą metody POST.

W teorii wszystko zawsze ładnie wygląda, jednak w praktyce nie jest za ciekawie. Pisząc prototypowy program, komenda send z Winsock przy drugiej próbuje użycia tak jakby nie działała. Próbowałem bawić się w rozłączanie, a następnie ponownie łączenie, ale odrzucało mnie. Co więcej, jeśli na początek zamiast GET wyśle od razu paczuszkę POST to wszystko śmiga jak należy.

Kod:
C/C++
#include <iostream>
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <windows.h>

using namespace std;


int main( int argc, char ** argv ) {
   
    system( "cls" );
    cout << "[>Winsock simple GET/POST method<]\n\n";
   
    WSADATA wsaData;
   
    if( WSAStartup( MAKEWORD( 2, 2 ), & wsaData ) != 0 ) {
        cout << "]WSAStartup failed.\n";
        system( "pause" );
        return 1;
    }
   
    SOCKET Socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
   
    struct hostent * host;
    host = gethostbyname( "222.42.1.232" );
   
    SOCKADDR_IN SockAddr;
    SockAddr.sin_port = htons( 83 );
    SockAddr.sin_family = AF_INET;
    SockAddr.sin_addr.s_addr = *(( unsigned long * ) host->h_addr );
    //SockAddr.sin_addr.s_addr = inet_addr( "173.164.192.9" );
   
   
    cout << "]Connecting to proxy in China (" << "222.42.1.232:83" << ") ...\n";
    if( connect( Socket,( SOCKADDR * )( & SockAddr ), sizeof( SockAddr ) ) != 0 ) {
        cout << "]Could not connect!\n";
        system( "pause" );
        return 0;
    }
    cout << "]Connected.\n";
   
   
    cout << "]Sending:\n\nGET <ADRES> HTTP/1.1\r\nConnection: close\r\nHost: <ADRES>\r\n\r\n\n";
    cout << "]Send says: " << send( Socket, "GET <ADRES> HTTP/1.1\r\nConnection: close\r\nHost: <ADRES>\r\n\r\n\n", strlen( "GET <ADRES> HTTP/1.1\r\nConnection: close\r\nHost: <ADRES>\r\n\r\n\n" ), 0 ) << "\n";
    char buffer[ 20 ];
   
    cout << "\n]Receiving...\n";
    int nDataLength, totalRecvData;
    nDataLength = recv( Socket, buffer, 20, 0 );
    while( nDataLength > 0 ) {
        totalRecvData += nDataLength;
        int i = 0;
        while( buffer[ i ] >= 32 || buffer[ i ] == '\n' || buffer[ i ] == '\r' ) {
            cout << buffer[ i ];
            i += 1;
        }
        nDataLength = recv( Socket, buffer, 20, 0 );
    }
    cout << "]Data recived: " << totalRecvData;
    cout << "\n]Data throwed away: " << recv( Socket, buffer, 20, 0 ) << "\n"; //dla pewnosci ze nic nie zostalo
   
    //
    //
    //Tu wycięty fragment pracy na plikach
    //
    //
   
   
    string POSTcmd = "POST <ADRES> HTTP/1.1\r\nHost: <ADRES>\r\nConnection: keep-alive\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 43\r\n\r\n";
    POSTcmd += "<DANE FORMULARZA>\r\n\r\n";
    cout << "]Sending:\n" << POSTcmd;
    cout << "]Send says: " << send( Socket, POSTcmd.c_str(), POSTcmd.length(), 0 ) << "\n";
   
    cout << "\n]Receiving...\n";
   
    totalRecvData = 0;
    nDataLength = recv( Socket, buffer, 20, 0 );
   
    while( nDataLength > 0 ) {
        totalRecvData += nDataLength;
        int i = 0;
        while( buffer[ i ] >= 32 || buffer[ i ] == '\n' || buffer[ i ] == '\r' ) {
            cout << buffer[ i ];
            i += 1;
        }
        nDataLength = recv( Socket, buffer, 20, 0 );
    }
    cout << "\n]Recieved.\n";
    cout << "]Data recived: " << totalRecvData;
    cout << "\n]Data throwed away: " << recv( Socket, buffer, 20, 0 ) << "\n"; //dla pewnosci
   
    cout << "]Closing connection.\n";
    closesocket( Socket );
    WSACleanup();
    cout << "\n\n >END< \n\n";
    system( "pause" );
    return 0;
}

Byłbym bardzo wdzięczny jakby ktoś mógłby mi pomóc "przedłużyć żywotność" komunikacji z serwerem.

Pozdrawiam i z góry dziękuje,
matthias.
P-82117
maly
» 2013-05-05 18:57:13
Connection: close zamyka połączenie.
P-82123
matthias
Temat założony przez niniejszego użytkownika
» 2013-05-05 19:03:29
Poprawiłem na keep-alive, wciąż bez zmian, nic nie odbiera.
P-82124
maly
» 2013-05-05 19:23:17
Na końcu GET-a masz \n\n powinno być \r\n
P-82126
matthias
Temat założony przez niniejszego użytkownika
» 2013-05-05 19:31:19
Poprawiłem końcówkę GET na "\r\n\r\n". Wciąż bez zmian
P-82127
maly
» 2013-05-05 19:43:43
Jestem na komórce i nie mogę przetestować kodu ale jeśli POST działa to GET też powinien.
P-82128
matthias
Temat założony przez niniejszego użytkownika
» 2013-05-05 19:48:19
Tzn. W kodzie który podesłałem GET się wykonuje, a POST już nie.

Jeśli wywalę fragment GET, i samo POST zostanie, to wtedy POST działa. Po kilku próbach okazało się, że send() użyte po raz drugi nie działa.
P-82129
DejaVu
» 2013-05-29 22:35:33
Czyli problem rozwiązałeś tj. zakładam, że przerobiłeś kod tak, aby łączył się każdorazowo od nowa z serwerem w celu pobrania strony.
P-84306
« 1 »
  Strona 1 z 1