首页 > 解决方案 > 尝试打开 TCP 套接字时出错 - C++

问题描述

在此处输入图像描述

我正在尝试构建一个充当服务器和客户端的块,以通过 TCP 连接发送和接收数据(2 台不同计算机中的 2 个重复版本)。

这就是我所做的,我正在尝试使用 Windows 命令行“netstat -ab”进行测试以尝试查找 tcp 连接,但我找不到它。

除了给定的错误,我做错了什么?

bool IPTunnel::runBlock(void) {
    int ready =
        inputSignals[0]->ready(); // int ready2 = inputTCPConnetion[0]->ready();

    // server
    SOCKET sockfd, newsockfd;
    int portno;
    socklen_t clilen;
    char buffer[256];
    struct sockaddr_in serv_addr, cli_addr;
    SOCKET n;

    // create a socket(int domain, int type, int protocol)
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0) printf("\n ERROR opening socket");


    // bzero((char *)&serv_addr, sizeof(serv_addr));

    portno = 5500;


    serv_addr.sin_family = AF_INET;
    char ipad[10] = "127.0.0.1";
    serv_addr.sin_addr.s_addr = *ipad; // INADDR_ANY;
    serv_addr.sin_port = htons(portno);



    // if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
    auto sd = bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
    // if (sd < 0)
    //  printf("\n ERROR on binding");


    listen(sockfd, 5);

    clilen = sizeof(cli_addr);

    newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &clilen);
    if(newsockfd < 0) printf("ERROR on accept");

    printf("server: got connection from %s port %d\n",
           inet_ntop(serv_addr.sin_family, &ipad, buffer, clilen),
           ntohs(cli_addr.sin_port));

    send(newsockfd, "Hello, world!\n", 13, 0);

    // bzero(buffer, 256);

    n = _read(newsockfd, buffer, 255);
    if(n < 0) printf("ERROR reading from socket");
    printf("Here is the message: %s\n", buffer);
    while(true) {
    }
    // close(newsockfd);
    // close(sockfd);
    return 0;
}

这是给出的错误: ip_tunnel.exe 中 0x00007FFE5031B7EC (ucrtbased.dll) 处的未处理异常:将无效参数传递给认为无效参数致命的函数。

在 _read 函数中...

标签: c++visual-studiotcp

解决方案


好吧,这行肯定是错误的:

serv_addr.sin_addr.s_addr = *ipad; //INADDR_ANY;

如果你想在回送设备上接收传入的 TCP 连接,你应该做更多这样的事情:

serv_addr.sin_addr.s_addr = inet_aton("127.0.0.1");

(或者如果您希望从任何连接的网络设备接收它们,请改为指定 INADDR_ANY)

此外,请确保您WSAStartup()在程序开始时调用,如果您没有这样做,Windows 套接字将无法正常工作。

最后一个挑剔:

while(true){}

不是暂停程序执行的好方法。一方面,它通常会以 100% 的使用率旋转 CPU,这是非常低效的,另一方面,它会根据 C++ 标准调用未定义的行为。

获得这种行为的更好方法是:

while(true) {Sleep(1000);}

这部分也是错误/奇怪的:

SOCKET n;
[...]
n = _read(newsockfd, buffer, 255);

...在那个_read不返回 a SOCKET,它返回一个int。我想你的意思是声明int n;

最后一个潜在问题:如果您的调用bzero(buffer, 256);被注释掉,那么在调用返回buffer后很可能不包含零字节,在这种情况下,您之后的调用可能会读取到数组末尾并输出到狂野的蓝色在其他内存之外,可能会导致崩溃(或至少导致打印大量垃圾字节)。解决方法是确保数组在调用放置的有效字节的末尾包含一个 0/​​NUL 字节。_read()printf("Here is the message: %s\n", buffer);bufferbuffer_read()


推荐阅读