套接字服务器以缓冲区大小接收数据

我依次发送不同大小的数据包,如何以我发送的大小分别接收数据包,而不将其累积在缓冲区中。看来现在服务器将添加到缓冲区中,直到它填满为止,然后我就可以对其进行处理了。

示例:

缓冲区大小:84。

从客户端发送:84字节,76字节,76字节,80字节

在服务器中接收:84个字节,84个字节,84个字节,64个字节。

我想在发送邮件时收到它们。有可能吗?

    int port = stoi(getconfig("server_port"));
    std::string ipAddress = getconfig("ip_address");

    // Create a socket
    int listening = socket(AF_INET,SOCK_STREAM,0);
    if (listening < 0){
        std::cerr << "Can't create a socket!" << endl;
        Logger("Can't create a socket!");
        exit(-1);
    }
    std::cout << "The socket server was created successfully." << endl;

    // Bind the socket to a IP / port
    sockaddr_in hint;
    hint.sin_family = AF_INET;
    hint.sin_port = htons(port);
    inet_pton(AF_INET,ipAddress.c_str(),&hint.sin_addr);

    if (bind(listening,(sockaddr*)&hint,sizeof(hint)) < 0){
        cerr << "Can't bind to IP/port!" << endl;
        Logger("Can't bind to IP/port!");
        exit(-1);
    }

    // Mark the socket for listening in
    if (listen(listening,SOMAXCONN) < 0){
        cerr << "Can't listen!" << endl;
        Logger("Can't listen!");
        exit(-1);
    }

    // accept a call
    sockaddr_in client;
    socklen_t clientSize = sizeof(client);
    char host[NI_MAXHOST];
    char svc[NI_MAXSERV];

    while(true){
        int clientsoket = accept(listening,(sockaddr*)&client,&clientSize);
        if(clientsoket < 0){
            cerr << "Problem with client connecting!" << endl;
            Logger("Problem with client connecting!");
            break;
        }
        cout << "The client whas conected successfully." << endl;

        memset(host,NI_MAXHOST);
        memset(svc,NI_MAXSERV);

        int result = getnameinfo((sockaddr*)&client,clientSize,host,NI_MAXHOST,svc,NI_MAXSERV,0);
        if(result == 0) {
            cout << host << " connected on " << svc << endl;
        } else {
            inet_ntop(AF_INET,&client.sin_addr,NI_MAXHOST);
            cout << host << " connected on " << ntohs(client.sin_port) << endl;
        }

        // While receiving
        char buff[84];
        while(true){
            // Clear the buffer
            memset(buff,sizeof(buff));

            // Wait for a message
            int bytesRecv = recv(clientsoket,buff,sizeof(buff),0);
            if(bytesRecv < 0){
                cerr << "There was a connection issue!" << endl;
                Logger("There was a connection issue!");
                break;
            }

            if(bytesRecv == 0){
                cout << "The client disconnected." << endl;
                Logger("The client disconnected");
                break;
            }

            cout << "bytesRecv: " << bytesRecv << endl;
       }

       // Close the socket
       close(clientsoket);
    }

iCMS 回答:套接字服务器以缓冲区大小接收数据

不,流套接字不能那样工作。

流套接字是无结构的字节流,没有任何结构。在这方面,它与普通文件没有什么不同。如果您将各种大小的记录写到一个普通文件中,并且现在准备将它们读回,那么如何期望读取大小可变的记录?

无论您在此处给出的答案是什么,插座都适用相同的答案,而且插座上的read()会给您带来额外的扭曲,因此无法保证您会阅读多少书,只是小于或等于size的{​​{1}}参数。这是您从read()获得的唯一保证。

如果发件人两次调用read()(顺便说一句,套接字也不能保证无论您想write()多少写多少东西,write也可以保证返回小于或等于其write参数的字节数,这由您的代码确定如何处理),一次写入76个字节,第二次写入84个字节,size在初始读取时(假定缓冲区大小足够大)可以读取1到160字节之间的任意数量的字节。

如果您希望实现某种形式的结构,某种记录,则由您自己决定如何在这些限制内实现它。也许通过发送每个记录的大小(以字节为单位),然后发送记录本身。或做任何你想做的。请记住,您无法保证read()的回报是多少。例如,如果您要首先发送记录计数,则为四个字节的值。您的初始read()可能返回一个,两个或三个字节。您的代码必须准备好处理所有可能的情况。

本文链接:https://www.f2er.com/2130799.html

大家都在问