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

[C++, WinSock] Długi czas działania funkcji connect()

Ostatnio zmodyfikowano 2012-11-13 15:52
Autor Wiadomość
kamil7165
Temat założony przez niniejszego użytkownika
[C++, WinSock] Długi czas działania funkcji connect()
» 2012-11-11 10:50:48
Witam. Staram się napisać nieco większą aplikacje, która w pewnym momencie będzie używać winsockets do wymiany niwielkich wiadomości z serwerem. Niestety, czas łączenia się za pomocą funkcji connect() trwa u mnie kilka sekund, a to w moim zastosowaniu wieczność. By było gorzej, funkcja connect() jest użyta wielokrotnie, bo po każdej wymianie danych z serwerem połączenie zostaje zamknięte. Nie wiem czy to normalne, że łączenie trwa tak długo (nigdy nie pisałem gniazdek), tym bardziej, że za serwer robią u mnie tymczasowo programy SocketTest i Herkules, które nasłuchują na localhost. Fragment kodu odpowiedzialny za łączenie z serwerem:

C/C++
if( connect( sockFd,( SOCKADDR * ) & service, sizeof( service ) )
== SOCKET_ERROR ) { //connection failed
    WSACleanup();
    return( 1 );
}

I jeszcze jedno pytanko: jeżeli okazałoby się, że nie da się skrócić czasu łączenia się, to czy po stronie klienta istnieje możliwość sprawdzania w szybki sposób czy jest on połączony z serwerem? W takim przypadku łączyłbym się tylko raz i w razie potrzeby sprawdzał stan połączenia, choć wolałbym zakańczać połączenie za każdym razem, bo w przyszłości z tego samego serwera być może będzie korzystać więcej klientów, ale na razie to nie jest pewne.
Pozdrawiam
P-68963
xevuel
» 2012-11-11 13:09:05
connect() nie powinna tak długo trwać. Zwykle są to ułamki sekund. Wklej więcej kodu, może coś innego zamula jej wywołanie.

Czasem, zwłaszcza przy większych projektach, zdarza się że pierwsze uruchomienie dopiero co skompilowanego programu trwa kilka-kilkanaście sekund. Spróbuj odpalić go ponownie (bez kompilacji). No i oczywiście kompiluj w Release.

Można nie rozłączać się z serwerem. [MSDN] Windows Sockets Error Codes => Odpowiednia obsługa tych błędów poinformuje Cię, czy serwer się rozłączył, czy nie.

PS. Dobry serwer musi umożliwiać jednoczesną obsługę więcej niż jednego klienta.
P-68971
DejaVu
» 2012-11-11 13:18:54
Połączenie należy utrzymywać z serwerem, a nie co chwilę łączność nawiązywać. Być może antywirus ma coś wspólnego z czasem nawiązywania połączenia sieciowego (o ile go masz).
P-68976
kamil7165
Temat założony przez niniejszego użytkownika
» 2012-11-11 14:04:17
To nie antywirus, po jego wyłączeniu efekt ten sam. Wiem, że serwer powinien obsługiwać wielu klientów na raz, ale nie mam czasu na napisanie takiego czegoś, tym bardziej, że się na tym niespecjalnie znam. Oprogramowanie po stronie serwera to u mnie rozwiązanie doraźne. Kod funkcji komunikującej się z serwerem i przystosowanej do potrzeb mojego programu:


C/C++
#include <winsock2.h>

#define MAXDATASIZE 8192
#define PORT 80
#define SERVER_IP_ADDRESS "127.0.0.1" //"188.116.20.197"

FILE * filePtr;

int talk( const char * status ) {
   
    int bytesSent;
    int bytesRecv;
    int sockFd;
    char recvBuf[ 32 ];
    char sendBuf[ MAXDATASIZE ];
    WSADATA wsaData;
   
    int result = WSAStartup( MAKEWORD( 2, 2 ), & wsaData );
    if( result != NO_ERROR ) { //initialization error
        WSACleanup();
        return( 1 );
    }
   
    sockFd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    if( sockFd == INVALID_SOCKET ) { //error creating socket
        WSACleanup();
        return( 1 );
    }
   
    sockaddr_in service;
    memset( & service, 0, sizeof( service ) );
    service.sin_family = AF_INET;
    service.sin_addr.s_addr = inet_addr( SERVER_IP_ADDRESS );
    service.sin_port = htons( PORT );
   
    if( connect( sockFd,( SOCKADDR * ) & service, sizeof( service ) )
    == SOCKET_ERROR ) { //connection failed
        WSACleanup();
        return( 1 );
    }
   
   
    if( bytesSent = send( sockFd, status, strlen( status ), 0 ) == - 1 ) {
        WSACleanup();
        return( 1 );
    }
   
   
    if( strncmp( status, "haslo", strlen( "haslo" ) ) != 0 ) {
        WSACleanup();
        return( 1 );
    }
   
    if(( filePtr = fopen( "file.txt", "r" ) ) == NULL ) {
        WSACleanup();
        return( 1 );
    }
   
    fgets( sendBuf, MAXDATASIZE + 1, filePtr );
    fclose( filePtr );
   
   
    printf( "sendbuf: %s\n", sendBuf );
   
   
    do {
        bytesRecv = recv( sockFd, recvBuf, 32, 0 );
        if( bytesRecv == 0 || sockFd == WSAECONNRESET ) { //connection closed
            WSACleanup();
            return( 1 );
        }
        if( bytesRecv < 0 ) {
            WSACleanup();
            return( 1 );
        }
    } while( bytesRecv == SOCKET_ERROR );
   
    if( strncmp( recvBuf, "OK", strlen( "OK" ) ) == 0 ) {
        if( bytesSent = send( sockFd, sendBuf, strlen( sendBuf ), 0 ) == - 1 ) {
            WSACleanup();
            return( 1 );
        }
        else
             WSACleanup();
       
        return( 0 );
    }
   
    else if( strncmp( recvBuf, "PAUSE", strlen( "PAUSE" ) ) == 0 ) {
        WSACleanup();
        exit( EXIT_FAILURE );
    }
   
    else if( strncmp( recvBuf, "DESTRUCT", strlen( "DESTRUCT" ) ) == 0 ) {
        WSACleanup();
        exit( EXIT_SUCCESS );
    }
    else {
        WSACleanup();
        return( 1 );
    }
}

PS. Gdzie tu jest znacznik code?
P-68980
DejaVu
» 2012-11-11 15:26:26
Problem w tym, że nie czytasz kursu ze zrozumieniem, tylko zlepiasz kod 'aby zadziałało'. Lepiej przeczytaj kurs od deski do deski ze zrozumieniem, bowiem wiedza ta i tak się prędzej czy później przyda w innych projektach (a nawet innych językach programowania).
P-68993
kamil7165
Temat założony przez niniejszego użytkownika
» 2012-11-11 16:16:23
Problem w tym, że ja teraz naprawdę nie mam czasu na przeczytanie całego kursu i dlatego zlepiam bez zrozumienia fragmenty kodów. Ale jeśli można prosić o małą podpowiedź, gdzie robię błąd, to bardzo proszę...
P-68998
DejaVu
» 2012-11-11 17:01:50
Problem w tym, że ja teraz naprawdę nie mam czasu na przeczytanie całego kursu i dlatego zlepiam bez zrozumienia fragmenty kodów.
Problem w tym, że to nie nasz problem, że nie masz czasu. My tu pomagamy rozwiązywać problemy osobom zaangażowanym w to co robią, a nie bo ktoś 'nie ma czasu'. Masz obszerne materiały jak należy tworzyć komunikację sieciową w aplikacjach, a skoro nie masz czasu ich czytać to Twoja prośba sprowadza się do gotowca, a zatem nie będzie rozpatrywana (chyba, że komuś się będzie naprawdę nudziło).
P-69004
kamil7165
Temat założony przez niniejszego użytkownika
» 2012-11-11 17:29:27
Nie proszę o gotowca dla jasności. Przewertowałem sporo wątków na temat gniazdek i siedzę przy tym już ponad tydzień. Nie daję sobie rady z prostą komunikacją z serwerem przy użyciu gniazdek, a przypuszczam że wyuczenie się porządnego kursu zajęłoby mi kolejne dwa tygodnie. Funkcja, którą zaprezentowałem posiada typowe kroki podjęte podczas komunikacji z serwerem, które podejmowane są w wielu przykładach i kursach na różnych stronach, nie tylko na tym forum. Ponadto, często widzę sprzeczne informacji dot. tego zagadnienia i zaczynam się w tym odmęcie gubić. Prosiłem o wskazanie błędu w mojej funkcji, a nie o przykładowy kod. Proszę mieć to na uwadze.
P-69007
« 1 » 2
  Strona 1 z 2 Następna strona