C ++ recv()问题

时间:2011-01-30 01:10:06

标签: c++ sockets

我想发一个字符串“你好”,但我只是“重新”。那是为什么?

void Accept()
{
    SOCKADDR_IN sock;
    int intsock = sizeof(sock);
    remoteSocket = ::accept(desc, (LPSOCKADDR)&sock,  &intsock);
    if(remoteSocket == -1)
    {
        cout << "Error in Accept()" << endl;
    }
    HandleConnection();
}

void HandleConnection()
{
    cout << "You are connected !!!" << endl;
    char* temp = new char[20];
    Recv(temp);
    cout << temp << endl;
}

void Send(const char* buffer)
{
    if((::send(remoteSocket, buffer, strlen(buffer), 0)) < 0)
    {
        cout << "Error in Send()" << endl;
    }
}

void Recv(char* buffer)
{
    int n = 0;
    while((n = ::recv(remoteSocket, buffer, strlen(buffer), 0)) 0)
    {
        buffer[n] = 0;
    }
}

~Server()
{
    WSACleanup();
}

};

int main()
{
    Server s;
    s.Initialize();
    s.Socket();
    s.Bind();
    s.Listen();
    while(1)
    {
        s.Accept();
    }
    return 0;
}

3 个答案:

答案 0 :(得分:5)

尽管@Billy ONeal指出了析构函数问题,但你在循环中执行recv(),但每次覆盖接收到的缓冲区。我相信你想要这样的东西:

// Pass buffer and its real size. This function takes care of NULL termination.
size_t Recv(char* buffer, size_t size) {
    size_t total = 0, n = 0;
    while((n = ::recv(remoteSocket, buffer+total, size-total-1, 0)) > 0) {
        total += n;
    }
    buffer[total] = 0;
    return total;
}

int main() {
    char buffer[128];
    // Connect or whatever (and set your global remoteSocket)
    Recv(buffer, sizeof(buffer));
    cout << buffer << endl;
    return 0;
}

答案 1 :(得分:3)

我认为问题在于这行代码while((n = ::recv(remoteSocket, buffer, strlen(buffer), 0)) 0)

您正在使用strlen(buffer)来获取不正确的缓冲区大小,您应该将sizeof(buffer)传递给Recv函数。

如果那不是问题那么它就是问题之一:P

编辑:

正如Kitsune和Mark指出的那样,sizeof(缓冲区)将返回4或8个字节,因为它是在堆上分配的,并且只是指向内存块的指针。如果您选择使用堆栈(char buffer[20]而不是new char[20]),则可以将sizeof(缓冲区)传递给Recv函数。否则,只需使用硬编码的20。

这就是你的代码应该是这样的:

void HandleConnection()
{
    cout << "You are connected !!!" << endl;
    char temp[20]; // <-- now we have an array
    Recv(temp, sizeof(temp)); // <-- sizeof(temp) will give us 20, not 4 anymore
    cout << temp << endl;
}

Recv(char* buffer, size_t buffer_size)
{
    recv(remoteSocket, buffer, buffer_size, 0);
}

答案 2 :(得分:2)

您需要指定接收数据的缓冲区大小 - 它不是strlen(buffer)

如果缓冲区数组在本地定义为数组(不在参数列表中),或者缓冲区是全局或文件范围数组,其定义在函数中可见,则可以使用sizeof(buffer)。否则,您需要使用传递给Recv()函数的额外缓冲区大小参数 - 也就是说,如果缓冲区是在另一个函数中定义的,或者是否是动态分配的。 (在代码中,数组定义在Recv()中不可见,因此您需要确保Recv()以某种方式知道大小 - 作为显式额外参数,或者因为您将缓冲区包装在一个适当的类,它包含一个方法,告诉你为它所拥有的缓冲区分配了多少空间。

当然,所显示的代码无法编译,因为buffer实际上并未在任何地方定义或声明。