c++ - recv() 没有获取客户端使用 send() 发送的所有数据

标签 c++ sockets network-programming send recv

我真的不知道这是否是某种网络延迟、我的电脑延迟或其他什么延迟,我对套接字编程还很陌生,并且一直在努力使它工作一段时间,实现一个简单的框架来在我类(class)的 future 项目中简化我的工作,我在我遇到的问题中使用这些功能:

void TCPSocket::send(const std::string& message, int flags) {

    if (isListening || !isConnected) {
        throw ConnectionException("Can't send message from a socket that is not connected");
    }

    int msgLength = message.length();
    int bytesLeft = msgLength;
    int bytesSent;
    const char* cMessage = message.c_str();

    while (bytesSent < msgLength) {

        const char* cMessageLeft = cMessage + bytesSent;

        int result = ::send(socketFd, cMessageLeft, bytesLeft, flags);
        if (result == -1) {
            throw ConnectionException("Could not send message. Error: " + std::string(strerror(errno)));
        }

        bytesLeft -= result;
        bytesSent += result;

    }

}

std::string TCPSocket::recv(unsigned int maxlen, int flags) {

    if (isListening || !isConnected) {
        throw ConnectionException("Can't receive message in a socket that is not connected");
    }

    char buffer[maxlen+1];
    int result = ::recv(socketFd, buffer, maxlen, flags);

    if (result == -1) {
        throw ConnectionException("Could not receive message. Error: " + std::string(strerror(errno)));
    }
    if (result ==  0) {
        isConnected = false;
        throw ClosedConnection("Client closed connection.");
    }
    buffer[result] = '\0';
    std::string message(buffer);

    return message;

}

它只处理一条消息就很好用,我使用不同的可执行文件接收和发送完全没有问题,但我尝试发送超过 1 条消息并且我的问题开始了,有时我让服务器接收 1 条消息,有时它什么也没有,当我只添加几个 printf() 时,它全部收到,有人可以向我解释为什么会这样吗?

客户端代码:

int main() {
    TCPSocket cl1(0);

    try {
        cl1.connect("localhost", 1170);
        for (int i = 0; i < 5; i++) {
            //printf("Esperando 5s... ");
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            //printf("Pronto!\n\n");

            cl1.send("Thank you!\n");
            //printf("Msg enviada\n\n");

        }
        cl1.close();
    }
    catch( std::exception &e) {
        std::cout << e.what() << std::endl;
    }
}

服务器代码:

int main() {
    TCPSocket sv1(0);

    try {
        sv1.bind(1170);
        sv1.listen();
        TCPSocket client = sv1.accept();
        printf("Cliente conectado\n");
        try {
            for (;;) {
                //client.send("Welcome !\n");
                std::cout << client.recv(256) << std::endl;
            }
        }
        catch (const ClosedConnection & x) {
            printf("Connection closed\n");
        }

    }
    catch( std::exception &e) {
        std::cout << e.what() << std::endl;
    }
}

如果我取消注释客户端代码中的 printfs,所有数据都会在服务器上接收。

澄清一下,我以 5 秒的间隔发送消息,recv() 仍然只读取第一个并且它会阻塞直到 client 完成它的执行,从不读取应该是的其余消息在缓冲区中。出于某种原因,在客户端代码上使用 printfs 可以使应用程序运行良好。

最佳答案

您似乎没有初始化 bytesSent,因此它实际发送数据的次数似乎不确定。

    int bytesSent = 0;

关于c++ - recv() 没有获取客户端使用 send() 发送的所有数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46126819/

相关文章:

c++ - 虚拟表中的条目数

c++ - 在不创建实例的情况下调用非静态成员函数

python - 保持套接字在线程中打开,并从Main发送命令

基于 UNIX 套接字的客户端程序中的 C++ connect() 不建立与服务器的连接

java - 当网络上的所有计算机都具有相同的公共(public) IP 地址时,如何向特定计算机发送 UDP 数据包?

c++ - C++ 对象数据成员的最佳数组类型?

c++ - 传递枚举数组是什么意思?

php - 如何为 set socks 5 或 php stream_socket_client 的 http 代理制作上下文数组

c - 关于UDP接收包时buffersize的问题

ios - 当分配的IP恰好相同时网络状态变化通知