【问题标题】:Error 11004 on Local NetWork with Winsock Client使用 Winsock 客户端的本地网络上出现错误 11004
【发布时间】:2017-12-13 15:47:44
【问题描述】:

问题

我正在使用代码作为服务器连接到 Hercules HW 终端上的 localhost,它可以工作。

然后我尝试在另一台计算机上的本地网络上的另一台计算机上设置服务器。

消息错误是针对 WSAGetLastError() 11004 给出的

怎么了?我就是想不通。

代码

使用 Winsock 的客户端的代码是:

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <string>
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <cstdlib>
#include <cstdio>
#include <time.h>


// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")


#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "2112"
#define DEFAULT_PROTO SOCK_STREAM

int main()
{
    char Buffer[128];
    // default to localhost
    char *server_name = "localhost";
    unsigned short port = atoi(DEFAULT_PORT);
    int retval, loopflag = 0;
    int i, loopcount, maxloop = -1;
    unsigned int addr;
    int socket_type = DEFAULT_PROTO;
    struct sockaddr_in server;
    struct hostent *hp;
    int first = 1;
    WSADATA wsaData;
    SOCKET  conn_socket;

    //    srand(time(NULL));
    if ((retval = WSAStartup(0x202, &wsaData)) != 0)
    {
        fprintf(stderr, "Client: WSAStartup() failed: Error %d\n", retval);
        WSACleanup();
        return -1;
    }
    else
        printf("Client: WSAStartup() is OK.\n");

    printf("Defina o nome ou IP do servidor[default = localhost]:\n");
    //    scanf( "%s" , Buffer );
    gets_s(Buffer);
    if (Buffer[0] != 0)
        server_name = Buffer;

    //    server_name = &Buffer;

    if (isalpha(server_name[0]))
    {   // server address is a name
        hp = gethostbyname(server_name);
    }
    else
    { // Convert nnn.nnn address to a usable one
        addr = inet_addr(server_name);
        hp = gethostbyaddr((char *)&addr, 4, AF_INET);
    }

    if (hp == NULL)
    {
        fprintf(stderr, "Client: Endereco IP nao identificado \"%s\": Error %d\n", server_name, WSAGetLastError());
        WSACleanup();
        exit(1);
    }
    else
        printf("Client: gethostbyaddr() esta OK.\n");
    memset(Buffer, 0, 128);
    printf("Defina a porta do server[default = 2112]:\n");
    gets_s(Buffer);
    if (Buffer[0] != 0)
        port = atoi(Buffer);

    memset(&server, 0, sizeof(server));
    memcpy(&(server.sin_addr), hp->h_addr, hp->h_length);
    server.sin_family = hp->h_addrtype;
    server.sin_port = htons(port);

    conn_socket = socket(AF_INET, socket_type, 0); /* Open a socket */
    if (conn_socket <0)
    {
        fprintf(stderr, "Client: Erro ao abrir o socket: Error %d\n", WSAGetLastError());
        WSACleanup();
        return -1;
    }
    else
        printf("Client: socket() esta OK.\n");

    printf("Client: Cliente conectando com: %s.\n", hp->h_name);

    conn_socket = socket(AF_INET, socket_type, 0); /* Open a socket */
    if (connect(conn_socket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
    {
        fprintf(stderr, "Client: connect() falhou: Error %d\n", WSAGetLastError());
        WSACleanup();
        return -1;
    }
    else
        printf("Client: connect() esta OK.\n");

    loopcount = 0;
    return 0;
}

使用Visual Basic 2015编译,带有:Project &gt; Properties &gt; Configuration Properties &gt; C/C++ &gt; Preprocessor &gt; Preprocessor Definitions

_WINSOCK_DEPRECATED_NO_WARNINGS
_CRT_SECURE_NO_WARNINGS

测试

  • 使用 telnetping 可以在使用 Hercules 硬件终端创建的其他服务器上运行。
  • 使用 Hercules HW 终端作为计算机 A 上的客户端和计算机 B 上的服务器也可以,所以我认为这与我的代码有关。
  • 使用nmap -p 2112 192.168.1.134

结果是:

Nmap scan report for 192.168.1.134

Host is up (0.00s latency).



PORT     STATE SERVICE

2112/tcp open  kip

MAC Address: 00:19:BB:F7:48:29 (Hewlett Packard)



Nmap done: 1 IP address (1 host up) scanned in 3.31 seconds

【问题讨论】:

    标签: c++ network-programming winsock


    【解决方案1】:

    来自https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx

    WSANO_DATA 11004

    有效名称,没有请求类型的数据记录。 请求的名称有效并且在数据库中找到,但它没有正确的关联数据正在解析。通常的示例是使用 DNS(域名服务器)的主机名到地址转换尝试(使用 gethostbyname 或 WSAAsyncGetHostByName)。返回一条 MX 记录,但没有 A 记录——表明主机本身存在,但不可直接访问。

    您的代码在gethostbyaddr(...) 失败。这是因为您路由器上的 DNS 没有您计算机的 DNS 记录。

    有了地址、端口和协议,你应该直接尝试用它连接到服务器。

    此外,gethostbyaddr 已被弃用:请参阅https://msdn.microsoft.com/en-us/library/windows/desktop/ms738521(v=vs.85).aspx

    有关如何设置套接字以进行连接的参考,请参阅http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#connect

    在beej 的代码中,您会看到一个getaddrinfo 调用。这支持如图所示的主机名或点 ip 字符串,因此您应该能够从示例中删除以下代码:

    if (isalpha(server_name[0]))
    {   // server address is a name
        hp = gethostbyname(server_name);
    }
    else
    { // Convert nnn.nnn address to a usable one
        addr = inet_addr(server_name);
        hp = gethostbyaddr((char *)&addr, 4, AF_INET);
    }
    

    【讨论】:

    • 我编辑了结果,虽然已经在那个端口上用 telnet 进行了测试
    猜你喜欢
    • 2019-10-18
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    • 1970-01-01
    • 2018-08-15
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多