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

[Winsock] Brak połączenia klienta z serwerem z dwóch różnych komputerów.

Ostatnio zmodyfikowano 2014-01-01 20:28
Autor Wiadomość
matka5432
Temat założony przez niniejszego użytkownika
[Winsock] Brak połączenia klienta z serwerem z dwóch różnych komputerów.
» 2013-12-29 21:17:29
Witam, dlaczego programy klient i serwer lacza sie ze soba tylko wtedy, gdy oba te programy sa uruchamiane na tym samym komputerze ? Jesli serwer (lub klient) jest na innym komputerze ( w tym samym domu - czyli to samo ip) klient nie laczy sie z serwerem. (Probowalem zmienic porty. Oczwiscie takie same w obu programach)
Oto kody:
serwer:
C/C++
#include <winsock.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>

using namespace std;

int main( int argc, int ** argv )
{
    WSADATA wsda; // informacja zwrocona przez WSAStartup
    char szRepMessage[ 80 ]; // komunikat zwrotny
    int iMessageLen;
    int ret;
    char szInBuffer[ 128 ]; // bufor na otrzymany komunikat
    int iBufferLen;
    int iPort, iAddrLen;
   
    SOCKET sListen, sClient; // gniazdo dla nasluchu oraz do klienta
    SOCKADDR_IN addr, remote_addr; // interfejs lokalny oraz polaczonego klienta
   
   
    // port na ktorym sie komunikujemy (0...65535)
    iPort = 1000;
   
    // zaladuj WinSock w wersji 2.2
    WSAStartup( MAKEWORD( 2, 2 ), & wsda );
   
    // stworzenie gniazda TCP
    sListen = socket( AF_INET, SOCK_STREAM, IPPROTO_IP );
   
    // sprawdzenie bledu
    if( sListen == SOCKET_ERROR )
    {
        cout << "Blad przy inicjalizacji gniazda : " << WSAGetLastError() << endl;
        system( "PAUSE" );
        exit( 1 );
    }
   
    // laczenie gniazda z adresem/portem
    addr.sin_family = AF_INET;
    addr.sin_port = htons( iPort );
    addr.sin_addr.s_addr = htonl( INADDR_ANY );
    ret = bind( sListen,( struct sockaddr * ) & addr, sizeof( addr ) );
   
    // sprawdzenie bledu
    if( ret == SOCKET_ERROR )
    {
        cout << "Blad przy wiazaniu gniazda : " << WSAGetLastError() << endl;
        system( "PAUSE" );
        exit( 1 );
    }
   
    // ustaw tryb nasluchu
    ret = listen( sListen, 10 );
   
    // sprawdzenie bledu
    if( ret == SOCKET_ERROR )
    {
        cout << "Blad przy trybie nasluchu : " << WSAGetLastError() << endl;
        system( "PAUSE" );
        exit( 1 );
    }
   
    // oczekiwanie na polaczenie
    cout << "Oczekiwanie na polaczenie (nacisnij CTRL-C zeby przerwac)..." << endl;
    iAddrLen = sizeof( remote_addr );
    sClient = accept( sListen,( struct sockaddr * ) & remote_addr, & iAddrLen );
   
    // sprawdzenie bledu
    if( sClient == SOCKET_ERROR )
    {
        cout << "Blad przy nawiazywaniu polaczenia : " << WSAGetLastError() << endl;
        system( "PAUSE" );
        exit( 1 );
    }
   
    cout << "Polaczono z hostem " << inet_ntoa( remote_addr.sin_addr ) << endl;
   
    // odbior komunikatu
    cout << "Oczekiwanie na odpowiedz..." << endl;
    ret = recv( sClient, szInBuffer, sizeof( szInBuffer ), 0 );
   
    // sprawdzenie bledu
    if( ret == SOCKET_ERROR )
    {
        cout << "Blad przy odbiorze komunikatu " << WSAGetLastError() << endl;
        system( "PAUSE" );
        exit( 1 );
    }
   
    // wyswietlenie komunikatu od klienta
    iBufferLen = ret;
    szInBuffer[ iBufferLen ] = '\0';
    cout << "Otrzymano komunikat o tresci \"" << szInBuffer << "\"" << endl;
   
    // wczytanie i wyslanie komunikatu zwrotnego
    cout << "Wpisz komunikat zwrotny...";
    cin.getline( szRepMessage, 80, '\n' );
    iMessageLen = strlen( szRepMessage );
    ret = send( sClient, szRepMessage, iMessageLen, 0 );
   
    // sprawdzenie bledu
    if( ret == SOCKET_ERROR )
    {
        cout << "Blad przy wysylaniu komunikatu zwrotnego : " << WSAGetLastError() << endl;
        system( "PAUSE" );
        exit( 1 );
    }
   
    // zamkniecie gniazda
    closesocket( sClient );
   
    // zamkniecie WinSock
    WSACleanup();
   
    system( "PAUSE" );
   
    return 0;
   
}
Klient:
C/C++
#include <winsock.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>

using namespace std;

int main( int argc, int ** argv )
{
    WSADATA wsda; // informacja zwrocona przez WSAStartup 80.54.127.254
    struct hostent * host; // informacja o serwerze
    char szMessage[ 80 ]; // komunikat
    int iMessageLen;
    int ret;
    char szInBuffer[ 128 ];
    int iBufferLen;
    char szAddress[ 64 ];
    int iPort;
   
    SOCKET s; // uzywane gniazdo
    SOCKADDR_IN addr; // adres hosta
   
   
    // pobranie adresu IP
    cout << "Podaj adres IP do ktorego wyslac (np. 127.0.0.1) ...";
    cin.getline( szAddress, 64, '\n' );
   
    // port na ktorym sie komunikujemy (0...65535)
   
    int porciczek = 1000;
   
    iPort = porciczek;
   
    // pobranie komunikatu do bufora
    cout << "Wpisz komunikat ...";
    cin.getline( szMessage, 80, '\n' );
   
    // dlugosc komunikatu
    iMessageLen = strlen( szMessage );
   
    // zaladuj WinSock w wersji 2.2
    WSAStartup( MAKEWORD( 2, 2 ), & wsda );
   
    // stworzenie gniazda TCP
    s = socket( AF_INET, SOCK_STREAM, IPPROTO_IP );
   
    // sprawdzenie bledu
    if( s == SOCKET_ERROR )
    {
        cout << "Blad przy inicjalizacji gniazda : " << WSAGetLastError() << endl;
        system( "PAUSE" );
        exit( 1 );
    }
   
    // informacja o hoscie
    addr.sin_family = AF_INET;
    addr.sin_port = htons( iPort );
    addr.sin_addr.s_addr = inet_addr( szAddress );
   
    if( addr.sin_addr.s_addr == INADDR_NONE ) // jesli nie podano numeru IP, to odnajdz go z DNS
    {
        host = NULL;
        cout << "Szukam hosta..." << endl;
        host = gethostbyname( szAddress ); // pobierz numer IP i go zachowaj
        if( host == NULL )
        {
            cout << "Nieznany host." << endl;
            system( "PAUSE" );
            exit( 1 );
        }
        memcpy( & addr.sin_addr, host->h_addr_list[ 0 ], host->h_length );
        cout << "OK." << endl;
    }
   
    // laczenie z serwerem
    cout << "Laczenie z hostem " << szAddress << " na porcie " << iPort << endl;
    ret = connect( s,( struct sockaddr * ) & addr, sizeof( addr ) );
   
    // sprawdzenie bledu
    if( ret == SOCKET_ERROR )
    {
        cout << "Blad przy laczeniu z serwerem : " << WSAGetLastError() << endl;
        system( "PAUSE" );
        exit( 1 );
    }
   
    // wyslanie komunikatu
    cout << "Wysylanie pakietu..." << endl;
    ret = send( s, szMessage, iMessageLen, 0 );
   
    // sprawdzenie bledu
    if( ret == SOCKET_ERROR )
    {
        cout << "Blad przy wysylaniu komunikatu : " << WSAGetLastError() << endl;
        system( "PAUSE" );
        exit( 1 );
    }
   
    // odbior komunikatu zwrotnego
    cout << "Oczekiwanie na komunikat zwrotny..." << endl;
    ret = recv( s, szInBuffer, sizeof( szInBuffer ), 0 );
   
    // sprawdzenie bledu
    if( ret == SOCKET_ERROR )
    {
        cout << "Blad przy odbiorze komunikatu zwrotnego : " << WSAGetLastError() << endl;
        system( "PAUSE" );
        exit( 1 );
    }
   
    // wyswietlenie komunikatu zwrotnego
    iBufferLen = ret;
    szInBuffer[ iBufferLen ] = '\0';
    cout << "Otrzymano komunikat o tresci \"" << szInBuffer << "\" od hosta " << szAddress << endl;
   
    // zamkniecie gniazda
    closesocket( s );
   
    // zamkniecie WinSock
    WSACleanup();
   
    system( "PAUSE" );
   
    return 0;
}
P-100581
Pokropow
123
» 2013-12-29 22:06:57
ip nie jest to samo. Ważne jest lokalne ip. Wpisz w konsolę "ipconfig" i tam powinno się wyświetlić. Takie ip zazwyczaj zaczynają się od "192." ale mogą się zaczynać inaczej.
P-100585
matka5432
Temat założony przez niniejszego użytkownika
» 2013-12-30 00:07:18
Hmm.. Wpisalem ip, ktore mi pokazalo w konsoli i rzeczywiscie dziala, jesli wysylam z pierwszego lapka, ktory jest polaczony z routerem do drugiego lapka, ktory tez jest z nim polaczony. Niestety kiedy wyslalem klienta koledze, nie doszla zadna wiadomosc na serwer. Podalem mu moje ip, ktore jest pokazane na stronach www ("moje ip" itp) te 2, ktore byly w konsoli tez mu podalem. Zadne z nich nie zadzialalo i nie udalo mu sie polaczyc z serwerem.
P-100599
Pokropow
port forwarding
» 2013-12-30 10:02:58
Ten kto ma na komputerze włączony serwer musi ustawić tak zwany port forwarding. Trzeba go zmienić w opcjach routera lub za pomocą specjalnej aplikacji (jak np simple port forwarder). Musisz przekierować port z którego korzystasz w aplikacji (z tego co widze w twojej aplikacji port 1000) na ip twojego komputera z serwerem.

Może użyłem trochę trudnego języka ale chodzi mniej więcej o coś takiego:
*wchodzisz na stronę routera, którą znajdziesz w jego instrukcji (jest to jakieś ip,np u mnie na routerze od tplink'a -> 192.168.1.1)
*wpisujesz login i hasło (domyślne hasła zazwyczaj są zapisane pod routerem albo w instrukcji, a jeżeli nie ich tam niema spróbuj coś w stylu login: admin, a hasło:      admin albo password)
*wchodzisz w zakładkę FORWARDING
*ustawiasz: IP -> ip wyświetlane u ciebie w ipconfig
            port-> wykorzystany port, jak np 1000
            protokół danych-> u ciebie chyba TCP

to co napisałem robisz tylko u posiadacza serwera! Klient po prostu łączy się z twoim ip po tym porcie.

Mam nadzieję, że pomogłem - sam wczoraj pisałem podobną aplikację i potrzebowałem pomocy na forum :) .
P-100610
matka5432
Temat założony przez niniejszego użytkownika
» 2013-12-30 11:54:28
Zrobilem to co mowiles.
1.Zalogowalem sie na stronie mojego routera.
2.Znalazlem zakladke "port forwarding".
3.Zaznaczylem dymek - enable port forwarding.
4.Ponizej dodalem nowy "Current Port Forwarding Table" z IP 192.168.0.1, czyli taki jak mam w ip config.
5.Typ protokolu ustawilem na TCP.
6.Port w zakresie 1000 - 1000.
7.Zostal jescze ostatni parametr Comment, ktorego pole pozostawilem puste, bo nie wiem co oznacza.
8.Dodalem tego "Table'a" (tak sie to nazywa ?)i zaakceptowalem.
Po odczekaniu 15 sec (byl odliczany czas) zmiany sie zaakceptowaly. Niestety nadal klient, ktory jest na kogos komputerze nie laczy sie z moim serverem.
P-100617
Pokropow
» 2013-12-30 12:06:50
"Table" tak się nazywa na twoim routerze a w luźnym tłumaczeniu znaczy to "tabelka na przekierowywane porty", a comment to po prostu komentarz.

Powiedz podczas czego wywala (w ogóle nie łączy, czy może błąd podczas przesyłu?) Jakie komunikaty wyświetla serwer i klient? Zaraz sprawdzę czy u mnie działa twój program(w celach testowych więc chyba mogę co nie?).
P-100619
matka5432
Temat założony przez niniejszego użytkownika
» 2013-12-30 13:47:37
Hehe, nie ma najmniejeszego problemu. Z reszta to nie jest moj program, sciagnalem to z internetu, poniewaz wole sie uczyc na przykladach niz z kursow. Oto komunikaty na hoscie:
Laczenie z hostem 192.168.0.1 na porcie 1000
Blad przy laczeniu z serwerem : 10060
aby kontynuowac ....

Nie ma zadnej reakcji ze strony servera (tak jak by w ogole nie uruchamiac hosta - server wciaz czeka na polaczenie), czyli najprawdopodobniej w ogole sie nie laczy.
P-100637
Pokropow
» 2013-12-31 14:30:52
Sorry,ale u mnie działają te aplikacje. Jeżeli jest jakiś błąd to doszukuj się go w routerze lub w ip. Poszukaj w sieci poradników o forwardowaniu portów do twojego routera i upewnij się że dobrze wpisałeś ip (do sprawdzania zewnętrzego ip polecam stronkę speedtest.pl).BTW błąd 10060 oznacza że minął czas na połączenie się z serwerem.
P-100746
« 1 » 2
  Strona 1 z 2 Następna strona