【问题标题】:how can i use GetAdaptersAddresses() to send ip address我如何使用 GetAdaptersAddresses() 发送 IP 地址
【发布时间】:2013-06-23 12:12:33
【问题描述】:

我正在尝试使用 TCP 在 C++ 中创建服务器和客户端程序,服务器将其 IP 地址发送到 Web 主机,然后客户端可以访问 Web 主机并获取服务器列表。 我正在尝试使用 GetAdaptersAddresses() 函数来发送服务器的 IP 地址,但我真的不知道该函数是如何工作的。我知道它需要 5 个参数,但我不知道为这些参数设置什么值。

这是所有服务器代码:

    #define WEBSITE         "server.x10host.com"    // Full website URL, withouth HTTP (raises exe size)
#define WEBPAGE         "/Server.php"               // The page of the Server Script (proceed with '\')


#define cAddIP          0       // Send this to the server, to add the IP to the list.
#define cRemIP          1       // Send this to the server, to remove the IP from the list.
#define cGetIPs         2       // Send this to the server, to get the list of all IPs.


SOCKET ListeningSocket;
SOCKADDR_IN ServerAddr;

int Port = 7171;
int MyIP;                       // Hold's the computers external IP (EG on an NAT)

// -------------------------




char* WebPost(char Website[], char Webpage[], char Request[], int RetLen) {
    // Sends an HTTP Post request with POST Data...
    // Absolutly NOT error checking, which needs fixing!

    SOCKET WebSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    struct hostent *WebHost;
    WebHost = gethostbyname(Website);
    if (WebHost == NULL) {

        if (WSAGetLastError() == WSANOTINITIALISED)
            printf("Error Not Connected!");
        else
            printf("Error: %d", WSAGetLastError());

        Sleep(1000);
        exit(0);

    }
    SOCKADDR_IN SockAddr;
    SockAddr.sin_port   = htons(80);
    SockAddr.sin_family = AF_INET;

    SockAddr.sin_addr.s_addr = *((unsigned long*)WebHost->h_addr);
    connect(WebSocket, (SOCKADDR*)(&SockAddr), sizeof(SockAddr));


    char PostRequest[1024];

    sprintf(PostRequest,
        "POST %s HTTP/1.1\r\n"
        "Host: %s\r\n"
        "Content-Length: %hu\r\n"
        "Content-Type: application/x-www-form-urlencoded\r\n"
        "\r\nD=%s\0",
        Webpage, Website,
        strlen(Request)+2, Request
    );

    send(WebSocket, PostRequest, strlen(PostRequest), 0);


    // Get return data ----------

    char* Data = new char[RetLen];
    recv(WebSocket, Data, 4, 0);

    for (;;) {                          // Skip HTTP headers...

        Data[0] = Data[1];
        Data[1] = Data[2];
        Data[2] = Data[3];

        recv(WebSocket, &Data[3], 1, 0);

        if (Data[0] == '\r' && Data[1] == '\n'
        &&  Data[2] == '\r' && Data[3] == '\n')
            break;

    }

    int DataLen = recv(WebSocket, Data, RetLen, 0);
    Data[DataLen] = '\0';   // Return the data...

    shutdown(WebSocket, 2);
    closesocket(WebSocket);
    return Data;

}



void ServStart() {

    WSADATA wsaData; 

    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
        printf("Server: WSAStartup failed with error %ld.\n", WSAGetLastError());
        exit(0);
    }

    printf("Server: The Winsock DLL found!\n");
    printf("Server: The current status is %s.\n\n", wsaData.szSystemStatus);

    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2 ) {
        printf("Server: The dll do not support the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion),HIBYTE(wsaData.wVersion));
        WSACleanup();
        exit(0);
    }

    printf("Server: The dll supports the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion),HIBYTE(wsaData.wVersion));


    // Start listening -----------------------------------------------
    ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (ListeningSocket == INVALID_SOCKET) {
        printf("Server: Error at socket, error code: %ld.\n", WSAGetLastError());
        WSACleanup();
        exit(0);
    }

    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_port = htons(Port);
    ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(ListeningSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR) {
        printf("Server: bind failed! Error code: %ld.\n", WSAGetLastError());
        closesocket(ListeningSocket);
        WSACleanup();
        exit(0);
    }

    if (listen(ListeningSocket, 5) == SOCKET_ERROR) {
        printf("Server: listen: Error listening on socket %ld.\n", WSAGetLastError());
        closesocket(ListeningSocket);
        WSACleanup();
        exit(0);
    }

    char SendBuf[32];
    MyIP = GetAdaptersAddresses();      // Get my IP
    sprintf(SendBuf, "%hhu|%s", cAddIP, MyIP);              // Send the server the IP
    WebPost(WEBSITE, WEBPAGE, SendBuf, 0);

    printf("Server: listening for connections...\n\n");

}

void ShutDown() {               // Shut down the server (tells the web server I am offline)

    char SendBuf[32];           // Remove my IP from the list of online servers...
    sprintf(SendBuf, "%hhu|%s", cRemIP, MyIP);
    WebPost(WEBSITE, WEBPAGE, SendBuf, 0);

    printf("Successful shutdown\n");
    Sleep(1000);

    WSACleanup();

}

有人可以帮我写一下这个函数的代码吗? 谢谢

【问题讨论】:

    标签: c++ visual-studio tcp client-server ip-address


    【解决方案1】:

    为什么需要发送自己的 IP 地址?建立任何形式连接的网络客户端将发送一个包含它的“返回地址”的数据包 - 这也是该服务器的地址。当然,除非您在防火墙内,情况会变得复杂,但在这种情况下,您可能不想发送本地计算机的 IP 地址,而是发送防火墙提供的 IP 地址。

    你只需要在服务器上这样的东西:

    <?php
    
    echo "Your address is " . $_SERVER['REMOTE_ADDR'] . "<br/>";
    
    ?>
    

    (如果你想用随机机器试试,可以试试这个:http://linuxhost.matsp.co.uk/calculator/my_ip.php

    【讨论】:

    • 但是获取外部IP地址。我想要运行服务器的计算机的地址 - IPv4 地址
    • 这意味着你在防火墙后面(或内置防火墙的路由器,或类似的东西),因此你想要服务器的外部地址。脚本位于 192.168.0.66 上的机器的本地 IP 不会从外部访问该机器。 81.158.216.91 将到达那台机器,因为那是外部 IP 地址。所以,如果你想让某人“选择一个服务器”,你需要外部地址。
    • 好吧,我只使用本地网络,所以我需要每台机器的本地 IP
    • 然后把你的服务器也放在里面... ;)
    【解决方案2】:

    让它工作 只需要将MyIP设置为MyIP = inet_ntoa(addr);

    【讨论】:

      猜你喜欢
      • 2018-09-19
      • 2012-01-12
      • 2012-01-21
      • 2016-05-28
      • 1970-01-01
      • 2014-10-19
      • 2017-06-30
      • 2012-06-06
      • 1970-01-01
      相关资源
      最近更新 更多