2010-11-26 181 views
3

我有一台服务器在一台机器上运行,并将它使用的端口转发到我的路由器,另一台运行客户端的服务器使用我的ISP分配的外部IP连接到服务器地址而不是本地地址。这一切工作正常,它连接,但当我检查连接的套接字(客户端)的地址时,它显示的IP地址是完全不同的?它显示我148.49.68.0。我无法在ipconfig上找到它,并且不明白这是从哪里弹出的。客户不应该显示我的外部地址吗? (看到两台计算机使用相同的外部IP地址)。确定服务器上连接的客户端的IP地址

[编辑]添加的服务器源

#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 =>国防部网络信息中心,哥伦布俄亥俄州。 – 2010-11-26 03:39:11

回答

8

试试这个:让外部IP的

#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

在Winsock getsockname()getpeername()函数分别返回所连接的套接字的本地和远程IP地址。假设您已经在使用它们,请显示您的实际代码,因为您可能没有正确使用它们。

+0

你好,我没有使用getsockname或getpeername,我认为sockaddr收到服务器的客户端已经拥有了这个。我将编辑上面的帖子,请告诉我如何。 – silent 2010-11-26 08:15:03

0

enter image description here

一个C/C++的方法是使用一个基于网络的IP地址的API工具,下载包含您的IP地址的网页到一个char数组并从HTML源中提取IP地址。这里有一些winsock代码来演示它。它使用http://api.ipify.org/的在线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; 
}