2010-11-26 11 views
3

Ich habe einen Server auf einem Computer ausgeführt und den Port, den es verwendet, an meinen Router weitergeleitet, und einen anderen Computer, der den Client unter Verwendung meiner externen IP-Adresse mit dem Server verbindet Adresse anstelle der lokalen Adresse. Das alles funktioniert gut und es verbindet sich aber wenn ich die Adresse des angeschlossenen Sockets (Client) überprüfe, ist die IP-Adresse, die es anzeigt, völlig anders? es zeigt mir 148.49.68.0. Ich kann das nicht auf ipconfig finden und verstehe nicht, woher es kommt. Sollte der Kunde meine externe Adresse nicht anzeigen? (Da beide Computer dieselbe externe IP-Adresse verwenden).Ermitteln der IP-Adresse eines verbundenen Clients auf dem Server

[EDIT] hinzugefügt Serverquelle

#include <iostream> 
#include <windows.h> 
#include <winsock2.h> 
#include <ws2tcpip.h> 
#include <string.h> 
using namespace std; 

int PORT; 
const int winsock_version = 2; 
const int max_con = 10; 
string SERVER_ADDRS; 

void Bind(SOCKET &serv,struct sockaddr_in &serv_info,int size); 
void Listen(SOCKET &serv,int max_con); 
void connection_info(struct sockaddr_in &client); 
bool communication(SOCKET &client); 
SOCKET Accept(SOCKET &serv); 

int main(void){ 

    WSADATA wsadata; 
    if (WSAStartup(MAKEWORD(winsock_version,0),&wsadata) == 0){ 
     cout<<"-[Initialized.]" << endl; 
     cout<<"-[Server Address (leave blank to scan for all IP's)]: "; 
     getline(cin,SERVER_ADDRS); 
     cout<<"-[Port]: "; 
     cin>>PORT; 

     struct sockaddr_in serv_info; 
     serv_info.sin_family = AF_INET; 
     serv_info.sin_port = htons(PORT); 
     if(sizeof(SERVER_ADDRS) > 5){ 
      cout<<"-[Listening on: " << SERVER_ADDRS << "]" << endl; 
      serv_info.sin_addr.s_addr = inet_addr(SERVER_ADDRS.c_str()); 
     }else{ 
      cout<<"-[Scanning for All IP's]" << endl; 
      serv_info.sin_addr.s_addr = INADDR_ANY; 
     } 

     SOCKET serv; 
     serv = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
     if (serv != INVALID_SOCKET){ 
      //------------------------------------------------------------ 
      Bind(serv,serv_info,sizeof(serv_info)); 
      Listen(serv,max_con); 


      struct sockaddr_in client_info; 
      int size = sizeof(client_info); 

      SOCKET client_sock = Accept(serv); 
      connection_info(client_info); 

      if (communication(client_sock) == true){ 
       closesocket(serv); 
       closesocket(client_sock); 
      } 
      //------------------------------------------------------------ 
     } 

    }else{ 
     cout<<"-[Initialization failed, running cleanup.]" << endl; 
    } 

    if (WSACleanup() == 0){ 
     cout<<"-[Cleanup Successful.]" << endl; 
    } 

    return 0; 
} 

void Bind(SOCKET &serv,struct sockaddr_in &serv_info,int size){ 

    if (bind(serv,(sockaddr*)&serv_info,size) != -1){ 
     //Binding complete, now clear the port and allow for reuse if needed using setsockopt 
     char yes = '1'; 
     if (setsockopt(serv,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) != SOCKET_ERROR){ 
       cout<<"-[Binding Successful.]" << endl; 
     } 
    } 
} 

void Listen(SOCKET &serv,int max_con){ 
    if (listen(serv,max_con) != -1){ 
     cout<<"-[Listening for connections.] " << endl; 
    } 
} 

SOCKET Accept(SOCKET &serv){ 

    struct sockaddr_in client_info; 
    int size = sizeof(client_info); 
    SOCKET recv; 

    recv = accept(serv,(sockaddr*)&client_info,&size); 
    if (recv != INVALID_SOCKET) { 
     return recv; 
    }else{ 
     cout<<"-[Invalid Socket.]" << endl; 
    } 
} 

void connection_info(struct sockaddr_in &client){ 
    char *connected_ip= inet_ntoa(client.sin_addr); 
    int port = ntohs(client.sin_port); 

    cout<<"-[IP:" << connected_ip <<", Connected on PORT:"<< port << "]"<< endl; 
} 

bool communication(SOCKET &client){ 
    cout<<"[---------------{CHAT}---------------]" << endl; 
    int bytes_in; 
    int bytes_out; 
    char recvd_text[80]; 
    string send_text; 

    while(true){ 
     cout<<"-[SERVER]: "; 
     getline(cin,send_text); 
     if (sizeof(send_text) > 0){ 
      bytes_out = send(client,send_text.c_str(),send_text.length()+1,0); 
      cout<< endl; 
      if (bytes_out == SOCKET_ERROR){ 
       cout<<"-[SERVER error in sending.]" << endl; 
       break; 
      } 
     } 

     bytes_in = recv(client,recvd_text,sizeof(recvd_text),0); 
     if (bytes_in > 0){ 
      cout<<"-[CLIENT]: " << recvd_text << endl; //output on screen 
     } 
     if (bytes_in == 0){ 
      cout<<"-[CLIENT has disconnected.]" << endl; 
      break; 
     } 
     if (bytes_in == SOCKET_ERROR){ 
      cout<<"-[CLIENT closed unexpectedly.]" << endl; 
      break; 
     } 

    } 
    return true; 
} 
+3

148.49.68.0 => DoD-Netzwerk-Informationszentrum, Columbus OH. –

Antwort

8

Try this:

#include <iostream> 
#include <windows.h> 
#include <winsock2.h> 
#include <ws2tcpip.h> 
#include <string> 

int PORT; 
const int winsock_version = 2; 
const int max_con = 10; 
std::string SERVER_ADDRS; 

void Bind(SOCKET &serv, const struct sockaddr_in &serv_info); 
void Listen(SOCKET &serv, int max_con); 
void connection_info(struct sockaddr_in &client); 
bool communication(SOCKET client); 
SOCKET Accept(SOCKET serv, sockaddr_in &client_info); 

int main(void) 
{ 
    WSADATA wsadata; 
    if (WSAStartup(MAKEWORD(winsock_version,0),&wsadata) == 0) 
    { 
     std::cout << "-[Initialized.]" << std::endl; 
     std::cout << "-[Server Address (leave blank to scan for all IP's)]: "; 
     std::getline(std::cin, SERVER_ADDRS); 
      std::cout << "-[Port]: "; 
     std::cin >> PORT; 

     struct sockaddr_in serv_info = {0}; 
     serv_info.sin_family = AF_INET; 
     serv_info.sin_port = htons(PORT); 
     if(SERVER_ADDRS.length() > 0) 
     { 
      std::cout << "-[Listening on: " << SERVER_ADDRS << "]" << std::endl; 
      serv_info.sin_addr.s_addr = inet_addr(SERVER_ADDRS.c_str()); 
     } 
     else 
     { 
      std::cout << "-[Scanning for All IP's]" << std::endl; 
      serv_info.sin_addr.s_addr = INADDR_ANY; 
     } 

     SOCKET serv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
     if (serv != INVALID_SOCKET) 
     { 
      //------------------------------------------------------------ 
      Bind(serv, serv_info); 
      Listen(serv, max_con); 

      struct sockaddr_in client_info = {0}; 

      SOCKET client_sock = Accept(serv, client_info); 
      if (client_sock != INVALID_SOCKET) 
      { 
       connection_info(client_info); 
       communication(client_sock); 

       closesocket(client_sock); 
      } 
      //------------------------------------------------------------ 

      closesocket(serv); 
     } 


     if (WSACleanup() == 0) 
     { 
      std::cout << "-[Cleanup Successful.]" << std::endl; 
     } 
    } 
    else 
    { 
     std::cout << "-[Initialization failed.]" << std::endl; 
    } 

    return 0; 
} 

void Bind(SOCKET serv, const struct sockaddr_in &serv_info) 
{ 
    //clear the port and allow for reuse before binding it 
    int yes = 1; 
    if (setsockopt(serv, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(yes)) != SOCKET_ERROR) 
    { 
     std::cout << "-[Reuse Address Successful.]" << std::endl; 
    } 

    if (bind(serv, (sockaddr*)&serv_info, sizeof(serv_info)) != -1) 
    { 
     std::cout << "-[Binding Successful.]" << std::endl; 
    } 
} 

void Listen(SOCKET serv, int max_con) 
{ 
    if (listen(serv, max_con) != -1) 
    { 
     std::cout << "-[Listening for connections.] " << std::endl; 
    } 
} 

SOCKET Accept(SOCKET &serv, sockaddr_in &client_info) 
{ 
    int size = sizeof(client_info); 
    SOCKET recv = accept(serv, (sockaddr*)&client_info, &size); 
    if (recv == INVALID_SOCKET) 
    { 
      std::cout << "-[Invalid Socket.]" << std::endl; 
    } 
    return recv; 
} 

void connection_info(struct sockaddr_in &client) 
{ 
    char *connected_ip = inet_ntoa(client.sin_addr); 
    int port = ntohs(client.sin_port); 

    st::cout << "-[IP:" << connected_ip << ", Connected on PORT:" << port << "]" << std::endl; 
} 

bool communication(SOCKET client) 
{ 
    std::cout << "[---------------{CHAT}---------------]" << std::endl; 
    int bytes_in; 
    int bytes_out; 
    char recvd_text[81]; 
    std::string send_text; 

    while(true) 
    { 
     std::cout << "-[SERVER]: "; 
     std::getline(std::cin,send_text); 
     if (send_text.length() > 0) 
     { 
      bytes_out = send(client, send_text.c_str(), send_text.length()+1, 0); 
      std::cout << std::endl; 
      if (bytes_out == SOCKET_ERROR) 
      { 
       std::cout << "-[SERVER error in sending.]" << std::endl; 
       break; 
      } 
     } 

     bytes_in = recv(client, recvd_text, sizeof(recvd_text)-1, 0); 
     if (bytes_in == SOCKET_ERROR) 
     { 
      std::cout << "-[CLIENT closed unexpectedly.]" << std::endl; 
      break; 
     } 
     else if (bytes_in == 0) 
     { 
      std::cout << "-[CLIENT has disconnected.]" << std::endl; 
      break; 
     } 
     else 
     { 
      recvd_text[bytes_in] = 0; 
      std::cout << "-[CLIENT]: " << recvd_text << std::endl; //output on screen 
     } 
    } 
    return true; 
} 
0

Die WinSock getsockname() und getpeername() Funktionen, um die lokalen und Remote-IP-Adressen der angeschlossenen Buchse zurückzukehren, respectively. Angenommen, Sie verwenden sie bereits, dann zeigen Sie bitte Ihren tatsächlichen Code an, da Sie sie wahrscheinlich nicht korrekt verwenden.

+0

Hallo, ich habe nicht getsockname oder getpeername verwendet, ich dachte, die sockaddr auf dem Server über den Client erhalten würde dies bereits halten. Ich werde den Beitrag oben bearbeiten, bitte berate mich wie. – silent

+2

Ja, accept() gibt Informationen über den verbundenen Client zurück. Es gibt jedoch einige Fehler in Ihrem Code. Der wichtigste Fehler in Bezug auf Ihre ursprüngliche Frage ist, dass Ihre Accept() - Funktion die Client-Informationen in eine sockaddr_in-Variable abruft, die nur für Accept() lokal ist, aber dann zeigt Ihre connection_info() -Funktion Werte von einem anderen sockaddr_in an local stattdessen main() und wurde nie mit irgendwelchen Daten gefüllt, so dass Sie zufälligen Müll anzeigen. Ihre Accept() - Funktion muss die sockaddr_in-Daten zurückgeben, die sie erhalten hat, und nicht verwerfen. –

0

enter image description here

One c/C++ Weg, um die externe IP zu bekommen ist ein Web-basierte IP-Adresse API-Tool zu verwenden, laden Sie die Website-Adresse in ein char Ihrer IP enthalten Array und extrahieren Sie die IP-Adresse aus der HTML-Quelle. Hier ist ein Winsock-Code, um es zu demonstrieren. es verwendet http://api.ipify.org/ 's online web api.

// 
// Winsock get external ip address from website api at api.ipify.org 
// api.ipify.org 
// 

#include <string.h> 
#include <stdio.h> 

#include <winsock2.h> 
#include <windows.h> 
#include <iostream> 
#include <vector> 

#include <algorithm> 
#include <cctype> 
#include <locale> 
#include <fstream> 
#include <ctime> 
#include <cstdlib> 

using namespace std; 
#pragma comment(lib,"ws2_32.lib") 


string website_HTML; 
locale local; 
char ipaddress[16]; 
int ic=0; 
void get_Website(char *url); 
char mystring[] = " "; 
char seps[] = " ,\t\n"; 
char *token; 
char lineBuffer[200][80] ={' '}; 
char buffer[10000]; 
char ip_address[16]; 
int i = 0, bufLen=0, j=0,lineCount=0; 
int lineIndex=0, posIndex=0; 


int main(void){ 

    SYSTEMTIME st; 
    GetLocalTime(&st); 
    char *today = new char[32]; 
    memset(today,' ', sizeof(today)); 
    sprintf(today,"%d-%d-%d", st.wYear , st.wMonth , st.wDay); 
    memset(buffer,'\0',sizeof(buffer)); 

    get_Website("api.ipify.org"); 
    for (size_t i=0; i<website_HTML.length(); ++i) website_HTML[i]= tolower(website_HTML[i],local); 

    token = strtok(buffer , seps); 
    while(token != NULL){ 

     strcpy(lineBuffer[lineIndex],token); 
     int dot=0; 
     for (int ii=0; ii< strlen(lineBuffer[lineIndex]); ii++){ 

      if (lineBuffer[lineIndex][ii] == '.') dot++; 
      if (dot>=3){ 
       dot=0; 
       strcpy(ip_address,lineBuffer[lineIndex]); 
      } 
     } 

     token = strtok(NULL, seps);  
     lineIndex++; 
    } 
    cout<<"Your IP Address is "<< ip_address<<" \n\n"; 

return 0; 
} 


void get_Website(char *url){ 
    WSADATA wsaData; 
    SOCKET Socket; 
    SOCKADDR_IN SockAddr; 
    int lineCount=0; 
    int rowCount=0; 
    struct hostent *host; 
    char *get_http= new char[256]; 

    memset(get_http,' ', sizeof(get_http)); 
    strcpy(get_http,"GET/HTTP/1.1\r\nHost: "); 
    strcat(get_http,url); 
    strcat(get_http,"\r\nConnection: close\r\n\r\n"); 

    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0){ 
     cout << "WSAStartup failed.\n"; 
     system("pause"); 
     //return 1; 
    } 

    Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
    host = gethostbyname(url); 

    SockAddr.sin_port=htons(80); 
    SockAddr.sin_family=AF_INET; 
    SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr); 

    if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) != 0){ 
     cout << "Could not connect"; 
     system("pause"); 
     //return 1; 
    } 
    send(Socket,get_http, strlen(get_http),0); 

    int nDataLength; 
    while ((nDataLength = recv(Socket,buffer,10000,0)) > 0){   
     int i = 0; 
     while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r'){ 

      website_HTML+=buffer[i]; 
      i += 1; 
     }    
    } 

    closesocket(Socket); 
    WSACleanup(); 
    delete[] get_http; 
}