3

我正在学习一个教我如何使用 win32 套接字(winsock2)的教程。我正在尝试创建一个连接到“localhost”的简单套接字,但是当我尝试连接到本地主机(在函数 connect() 处)时,我的程序失败了。

我需要管理员权限才能连接到本地主机吗?也许这就是它失败的原因?也许我的代码有问题?我已经尝试了端口 8888 和 8000,但它们都失败了。

此外,如果我将端口更改为 80 并连接到 www.google.com,我可以连接但我没有得到任何回复。那是因为我没有发送 HTTP 请求还是我打算得到一些响应?

这是我的代码(已删除包含):

// Constants & Globals //
typedef unsigned long IPNumber;    // IP number typedef for IPv4
const int SOCK_VER    = 2;
const int SERVER_PORT = 8888;  // 8888
SOCKET mSocket        = INVALID_SOCKET;
SOCKADDR_IN sockAddr  = {0};
WSADATA wsaData;
HOSTENT* hostent;


int _tmain(int argc, _TCHAR* argv[])
{
    // Initialise winsock version 2.2
    if (WSAStartup(MAKEWORD(SOCK_VER,2), &wsaData) != 0)
    {
        printf("Failed to initialise winsock\n");
        WSACleanup();
        system("PAUSE");
        return 0;
    }

    if (LOBYTE(wsaData.wVersion) != SOCK_VER || HIBYTE(wsaData.wVersion) != 2)
    {
        printf("Failed to load the correct winsock version\n");
        WSACleanup();
        system("PAUSE");
        return 0;
    }

    // Create socket
    mSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (mSocket == INVALID_SOCKET)
    {
        printf("Failed to create TCP socket\n");
        WSACleanup();
        system("PAUSE");
        return 0;
    }


    // Get IP Address of website by the domain name, we do this by contacting(??) the Domain Name Server
    if ((hostent = gethostbyname("localhost")) == NULL)  // "localhost"  www.google.com
    {
        printf("Failed to resolve website name to an ip address\n");
        WSACleanup();
        system("PAUSE");
        return 0;
    }

    sockAddr.sin_port             = htons(SERVER_PORT);
    sockAddr.sin_family           = AF_INET;
    sockAddr.sin_addr.S_un.S_addr = (*reinterpret_cast <IPNumber*> (hostent->h_addr_list[0]));
    // sockAddr.sin_addr.s_addr=*((unsigned long*)hostent->h_addr);  // Can also do this

    // ERROR OCCURS ON NEXT LINE: Connect to server
    if (connect(mSocket, (SOCKADDR*)(&sockAddr), sizeof(sockAddr)) != 0)
    {
        printf("Failed to connect to server\n");
        WSACleanup();
        system("PAUSE");
        return 0;
    }

    printf("Got to here\r\n");
    // Display message from server
    char buffer[1000];
    memset(buffer,0,999);
    int inDataLength=recv(mSocket,buffer,1000,0);
    printf("Response: %s\r\n", buffer);

    // Shutdown our socket
    shutdown(mSocket, SD_SEND);

    // Close our socket entirely
    closesocket(mSocket);

    // Cleanup Winsock
    WSACleanup();

    system("pause");
    return 0;
}
4

3 回答 3

3

由于您愿意使用基于连接的 TCP 协议,您将需要一个通信对应方,例如侦听端口 8888 的应用程序来响应您的连接启动请求( TCP 术语中的SYN -Packet)

您可以使用 unix 工具netcat(也可用于其他操作系统)来执行此操作,而无需管理员权限...

nc -l 8888

...在本地机器上的端口 8888 上打开一个监听套接字

但是,在 unix 系统上,您不允许在没有管理员权限的情况下侦听所谓的众所周知的端口。

有关TCP 连接生命周期的更多信息,请阅读

于 2011-11-26T09:38:57.157 回答
1

应该有人在您要连接的端口上监听。尝试编写一个小型服务器程序来侦听传入连接。如果连接成功显然您已连接到谷歌,但您需要发送一个 HTTP 请求(来自 C ? - 这会很困难)。

于 2011-11-26T10:14:55.577 回答
0

为了连接到 localhost 上的 TCP 端口,必须有人在你机器上的那个端口上监听。

除了编写您自己的服务器之外,还有一个简单的方法可以让一些程序监听:在您的机器上安装“简单 TCP/IP 服务”功能。这将为您提供端口 17 上的“每日报价”服务器、端口 13 上的 Daytime 服务器、端口 19 上的 Chargen 服务器和端口 7 上的 echo 服务器。

要安装它,请转到“程序和功能”或“添加/删除程序”或 Windows 上的任何名称,选择“打开或关闭 Windows 功能”并找到并安装“简单 TCPIP 服务”在列表。

于 2013-10-03T16:10:39.683 回答