【问题标题】:recv function always gives me the same bufferrecv 函数总是给我相同的缓冲区
【发布时间】:2015-06-11 09:06:25
【问题描述】:

这个问题是我之前提出的问题的后续问题。基本上我有一个在 ubuntu 中运行的 c++ 服务器,我现在正试图让这段代码在 Windows 中运行。我在使用 Windows 套接字时遇到了一些问题,因为这是我第一次使用它们。在套接字上接收数据遇到一些麻烦之后,我现在遇到了一些奇怪的事情:我传递给recv() 的缓冲区总是包含相同的数据。

当然,我检查了我的客户,它确实发送了一些不同的东西。 所以我一直在尽我最大的努力得到一些可以帮助我找出问题所在的东西。我在控制台上打印了recv() 接收到的字节数,并猜测它按预期发生了什么变化!所以我现在有点困惑,如果我传递给 recv() 的缓冲区的内容总是相同的,我不太明白接收到的字节数会有所不同。希望有人帮助找出原因。

这是我的代码:

int tcp_server::acceptConns()
{
    sockaddr_in from;
    bool infinite = true ;
    int fromlen=sizeof(from);
    /* Infinte loop to echo
 the IP address of the client */

    int readsize;
    char* message;
    char* clientmessage = (char*) malloc(256*sizeof(char));
    string smatrix ;
    int ind ;
    string tok;
    int i = 0 ;
    int bytesSent ;

    float matrix[16] ;
     do {
        readsize = recv(ClientSocket, clientmessage, 256, 0);
        if (readsize > 0) {
            printf("Bytes received: %d\n", readsize);
            message = "ack";
            bytesSent = send(ClientSocket, message, strlen(message),0);
            if(bytesSent == 0){
                std::cerr << "Error sending ACK" << endl ;
            }
            smatrix = clientmessage ;
            std::stringstream ss(smatrix);
            while(getline(ss, tok, ',') && i < 16 ){
                matrix[i] = static_cast<float>(::atof(tok.c_str()));
                i++ ;
            }
            coutMessage(matrix);
            message ="ok";
            bytesSent = send(ClientSocket, message, strlen(message),0);
            if(bytesSent == 0){
                std::cerr << "Error sending OK" << endl ;
            }
        }
        else if (readsize == 0)
            printf("Connection closing...\n");
        else  {
            printf("recv failed with error: %d\n", WSAGetLastError());
            closesocket(ClientSocket);
            WSACleanup();
            return 1;
        }

    } while (readsize > 0);

    // shutdown the connection since we're done
     readsize = shutdown(ClientSocket, SD_SEND);
     if (readsize == SOCKET_ERROR) {
        printf("shutdown failed with error: %d\n", WSAGetLastError());
        closesocket(ClientSocket);
        WSACleanup();
        return 1;
    }

    // cleanup
    closesocket(ClientSocket);
    WSACleanup();
    return 0 ;
}

提前感谢您为我提供的帮助。

【问题讨论】:

  • 由于大小是固定的,你可以说char clientmessage[256];而不是泄漏。
  • @LordZsolt 无休止的内存泄漏?
  • 是的,很明显,我想看看它是否与recv函数(我真的怀疑)或他的容器有关。
  • 您假设您将始终收到一个以零结尾的字符串,而没有其他任何内容。数据是一个流——你不能假设甚至有一个零,或者正好有一个。当您在分配的缓冲区之外读取时,这种假设几乎肯定会导致未定义的行为。
  • @LonniBesançon 将这个:smatrix = clientmessage ; 改为这个smatrix = string(clientmessage,readsize);原因是您要处理readsize 字符。第二种形式正确地提取了该数量的字符来创建字符串。事实上,当您应该使用 readsize 来限制实际接收的字符数时,您根本不会使用 readsizeif 语句除外)。

标签: c++ sockets winsock winsock2


【解决方案1】:
while(getline(ss, tok, ',') && i < 16 ){
    matrix[i] = static_cast<float>(::atof(tok.c_str()));
    i++ ;
}

由于您从未重置i,因此matrix 在第一次之后将永远不会更新。 recv 很好。

【讨论】:

  • 我不敢相信我已经对这个错误视而不见这么长时间了。我一直在寻找我们的。我假设这部分代码没有错,因为我已经在 Ubuntu 上工作了,但不知何故我忘了重新写下这一行。非常感谢您指出这一点。
猜你喜欢
  • 2014-05-14
  • 2012-04-04
  • 1970-01-01
  • 2016-09-30
  • 1970-01-01
  • 2020-09-15
  • 2015-07-29
  • 2020-05-05
  • 1970-01-01
相关资源
最近更新 更多