ไม่สามารถเชื่อมต่อกับไอพีระยะไกลได้

ฉันกำลังพยายามเชื่อมต่อไคลเอนต์กับเซิร์ฟเวอร์ ด้วยที่อยู่ในท้องถิ่น (127.0.0.1) ทุกอย่างทำงานได้ดีอย่างสมบูรณ์ แต่เมื่อฉันพยายามใช้ที่อยู่ระยะไกล มันก็ไม่ทำงาน ฉันค้นหาสิ่งนี้ทั่วอินเทอร์เน็ต แต่ไม่พบสิ่งใดเลย

ฝั่งเซิร์ฟเวอร์:

bool start_server()
{
    int i = 1;
    if(WSAStartup(MAKEWORD(2,0),&WsaDat) != 0)
    {
         cout << "WSA error!" << endl;
         system("pause");
         return FALSE;
    }
    if ( LOBYTE( WsaDat.wVersion ) != 2 || HIBYTE( WsaDat.wVersion ) != 0 )
    {
      cout << "Bad version of winsocket" << endl;
      system("pause");
      WSACleanup();
      return 0;
    }



    serwer = socket(AF_INET, SOCK_STREAM, 0);
    if(serwer == INVALID_SOCKET)
    {
        cout << "Can't create socketa!" << endl;
        system("pause");
        WSACleanup();
        return 0;
    }
    int port;
    cout << "Port input " << endl;
    cin >> port;                                             // 13056
    SOCKADDR_IN SockAddr;
    SockAddr.sin_port =  htons(port);
    SockAddr.sin_family = AF_INET;
    SockAddr.sin_addr.s_addr = INADDR_ANY;
    setsockopt( serwer, SOL_SOCKET, SO_REUSEADDR, ( char * ) &i, sizeof ( i ) );
    if(bind(serwer,(SOCKADDR *)(&SockAddr), sizeof(SockAddr)) == SOCKET_ERROR)
    {
        cout << "Couldn't bind socket" << endl;
        system("pause");
        WSACleanup();
        return 0;
    }
    for(int i = 0; i < MAX_CLIENTS; i++)
    client[i].connected = FALSE;
    if(listen(serwer,SOMAXCONN)==SOCKET_ERROR)
    {
        cout << "Listening error!" << endl;
        system("pause");
        WSACleanup();
        return 0;
    }
    cout << "Serwer created!" << endl;
    unsigned long b = 0;
    ioctlsocket ( serwer, FIONBIO, &b );
    return 1;
}

หลังจากนี้ฉันมีฟังก์ชั่นยอมรับที่โปรแกรมกำลังบล็อกอยู่:

accept(serwer,(SOCKADDR *)(&current_client->address),&current_client->address_length);

ด้านลูกค้า:

bool start_client()
{
    WSADATA WsaDat;

    if(WSAStartup(MAKEWORD(2,0),&WsaDat) != 0)
        cout << "WSA error!\n";
    if ( LOBYTE( WsaDat.wVersion ) != 2 || HIBYTE( WsaDat.wVersion ) != 0 )
    {
        cout << "Wrong version of winsocket\n";
        WSACleanup();
                    return false;
    }

    SOCKET Klient;

    Klient = socket(AF_INET, SOCK_STREAM, 0);
    if(Klient == INVALID_SOCKET)
            {
        cout << "Can't create socket socketa!\n";
        WSACleanup();
                    return false;
    }
    SOCKADDR_IN SockAddr;
    SockAddr.sin_port = htons(PORT);                        // 13056
    SockAddr.sin_family = AF_INET;
    SockAddr.sin_addr.S_un.S_addr = inet_addr("*********");      // my remote address
    while(connect(Klient, (SOCKADDR *)(&SockAddr), sizeof(SockAddr)) != 0) 
    {
        cout << "Trying to connect " << WSAGetLastError() << "\n";
        Sleep(500);
    }
    cout << "Connected!\n";
}

ฉันได้เพิ่มทั้งแอปพลิเคชันไคลเอ็นต์และเซิร์ฟเวอร์ลงในกฎไฟร์วอลล์แล้ว และฉันได้ลองเชื่อมต่อแอปพลิเคชันเหล่านั้นบนพอร์ตคู่ด้วย ฝั่งเซิร์ฟเวอร์กำลังรับฟังอย่างแน่นอน (ที่นี่บนพอร์ตอื่น):

ป้อนคำอธิบายรูปภาพที่นี่


person Blood    schedule 02.05.2013    source แหล่งที่มา
comment
ลองถอดชิ้นส่วนที่ไม่จำเป็นออก: SO_REUSEADDR และ FIONBIO แล้วคุณกำลังเชื่อมต่อกับที่อยู่ระยะไกลใด สิ่งที่ควรใช้งานได้คือที่อยู่ IP ที่แนบมากับ NIC ในเครื่องของคุณ ดูผลลัพธ์ของเช่น ไอพีคอนฟิก นอกจากนี้ คุณสามารถลองเชื่อมต่อกับเครื่องบางเครื่อง (เช่น เว็บเซิร์ฟเวอร์) บนอินเทอร์เน็ตได้ อย่างน้อยคุณก็ควรจะสามารถเชื่อมต่อได้   -  person Ulrich Eckhardt    schedule 02.05.2013
comment
รหัสข้อผิดพลาดใดที่ WSAGetLastError() ส่งคืนเมื่อ connect() ล้มเหลว   -  person Remy Lebeau    schedule 03.05.2013
comment
@Remy Lebeau - 10060 - หมดเวลาการเชื่อมต่อ   -  person Blood    schedule 03.05.2013
comment
@doomster - มันไม่ใช่ 127.0.0.1 และ 192.168.0.10 (ที่อยู่ในพื้นที่ของฉัน) ใช้งานได้ เมื่อฉันพยายามทำสิ่งนี้โดยตรวจสอบ IP ของฉันบน whatsmyip.org มันไม่ทำงาน :(   -  person Blood    schedule 03.05.2013
comment
@Blood: โมเด็มอินเทอร์เน็ตของคุณเชื่อมต่อโดยตรงกับพีซีของคุณหรือกับเราเตอร์เครือข่ายหรือไม่? หากเป็นอย่างหลัง คุณจะต้องกำหนดค่าเราเตอร์ให้ส่งต่อพอร์ตการเชื่อมต่อขาเข้าไปยังพีซีที่ใช้แอปเซิร์ฟเวอร์ของคุณ   -  person Remy Lebeau    schedule 03.05.2013


คำตอบ (1)


ไม่มีอะไรผิดปกติกับรหัสของคุณ

เราเตอร์และตัวแปลที่อยู่เครือข่าย (NAT) บางตัวไม่รองรับ hairpinning, ซึ่งเป็นความสามารถในการเชื่อมต่อกับ IP สาธารณะของคุณจากภายในเครือข่ายส่วนตัวที่อยู่ด้านหลัง NAT

หาก NAT/เราเตอร์ของคุณรองรับสิ่งนี้ คุณอาจต้องกำหนดค่ากฎการส่งต่อพอร์ตบน NAT/เส้นทางเพื่อแมปการรับส่งข้อมูล TCP ขาเข้าทั้งหมดบนพอร์ต 14354 (พอร์ตการรับฟังเซิร์ฟเวอร์ของคุณ) กับที่อยู่ IP ภายใน 192.168.0.10 . ลองคิดถึงสิ่งนี้จากมุมมองของเราเตอร์ หากเห็นและร้องขอการเชื่อมต่อขาเข้าบน IP สาธารณะ เราเตอร์จำเป็นต้องรู้ว่าโฮสต์ใดบนเครือข่ายส่วนตัวเพื่อส่งต่อการเชื่อมต่อนั้นไป

person selbie    schedule 03.05.2013