2010-11-26 35 views
3

J'ai un serveur en cours d'exécution sur une machine et le port qu'elle utilise est transféré vers mon routeur et un autre ordinateur qui exécute la connexion au serveur en utilisant mon adresse IP externe adresse au lieu de l'adresse locale. Tout cela fonctionne bien et il se connecte mais quand je vérifie l'adresse de la prise connectée (client), l'adresse IP qu'elle montre est complètement différente? il me montre 148.49.68.0. Je ne peux pas le trouver sur ipconfig et je ne comprends pas d'où cela vient. Le client ne devrait-il pas montrer mon adresse externe? (vu que les deux ordinateurs utilisent la même adresse IP externe).Détermination de l'adresse IP d'un client connecté sur le serveur

[EDIT] source du serveur ajouté

#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 => Centre d'information de réseau DoD, Columbus OH. –

Répondre

8

Essayez ceci:

#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

Les fonctions Winsock getsockname() et getpeername() renvoient les adresses IP locales et distantes de la douille reliée, respectivement. En supposant que vous les utilisez déjà, veuillez indiquer votre code réel, car vous ne les utiliserez probablement pas correctement.

+0

Bonjour, je n'ai pas utilisé getsockname ou getpeername, je me suis dit que le sockaddr reçu par le serveur à propos du client le tiendrait déjà. Je vais modifier le post ci-dessus, s'il vous plaît me conseiller comment. – silent

+2

Oui, accept() renvoie des informations sur le client connecté. Cependant, il y a quelques bugs dans votre code. Le bogue le plus important lié à votre question initiale est que votre fonction Accept() récupère les informations du client dans une variable sockaddr_in qui est locale uniquement à Accept(), mais votre fonction connection_info() affiche les valeurs d'une autre sockaddr_in qui est local à main() à la place et n'a jamais été rempli avec des données, de sorte que vous affichez des déchets aléatoires. Votre fonction Accept() doit retourner les données sockaddr_in qu'elle a récupérées, et non les ignorer. –

0

enter image description here

un c/C++ façon d'obtenir l'adresse IP externe est d'utiliser une API d'adresse IP sur le Web outil, téléchargez la page Web contenant votre adresse IP en char array et extrait l'adresse IP de la source HTML. Voici un code winsock pour le démontrer. il utilise l'API Web de http://api.ipify.org/.

// 
// 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; 
}