如何提取消息的长度信息,并从TCP字节流中只提取那么多消息? [英] How to extract length information of a message and extract only that much message from TCP bytes stream?

查看:942
本文介绍了如何提取消息的长度信息,并从TCP字节流中只提取那么多消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在c ++中通过Socket发送消息。我已经阅读了很多关于堆栈溢出相关的问题,但仍然不能弄清楚它是如何工作的。让我们说我将以下字符(M,a,r,t,i,n)发送到本地主机服务器,人们建议你可以使用4个字节作为长度(即32位,以便它可以处理一个消息到4GB长度)。

I am trying to send a message over Socket in c++. I have read many questions on stack overflow related to this but couldn't still figure out how it works. lets say i am sending following characters(M,a,r,t,i,n) to a local host server, people suggest that you can use 4 bytes as the length(i.e 32 bits, so that it can handle a message up to 4GB length).

我在客户端做了同样的事情,但仍然不知道我怎么能在服务器端找出这个东西,无论我想只接收开始3个字节(M, a,r)或我的数据的最后3个字节(t,i,n)。

I did the same thing at my client side but still dont know how can i figure out this thing at server side whether i want to receive only starting 3 bytes(M,a,r) or last 3 bytes(t,i,n) of my data.

我发布我的代码请帮助我主要在服务器端, thankfull如果可以写与代码相关的几行。

I am posting my code please help me mainly in the server side, will be thankfull if can write few lines with relevance to code.

           Client side code
std::vector<char> userbuffer(20);
std::cout<<"\nclient:"<<std::endl;
    char* p = userbuffer.data();
    *p = 'M';
            ++p; *p = 'a';
            ++p; *p = 'r';
            ++p; *p = 't';
            ++p; *p = 'i'; 
            ++p; *p = 'n';
            size_t length = strlen(userbuffer.data());
    uint32_t nlength = htonl(length);
            //line containg message length information
           int header_info = send(socketFD, (char*)&nlength, 4, 0); 
           // Data bytes send to the server
    int bytes_sent = send(socketFD, userbuffer.data(), length, 0);

    if(bytes_sent == SOCKET_ERROR){ //some errror handling}





 Server Side Code
 char receivebuffer[MAX_DATA] = { '\0' };
 int bytesReceivedFromClientMsg = 1;
 int length_bytes = 0;
 uint32_t length, nlength;
 //code to check length if we have received whole data length
 while(length_bytes < 4){
 int read = recv(clientSocket, ((char*)&nlength)+length_bytes, (4-length_bytes), 0);
 if (read == -1) { //error handling}
 length_bytes += read;}
// Most painfull section to understand.
// I implemented this code from some ideas on internet 
//but still cant find how its extracting length and what i am reading :(
       while(bytesReceivedFromClientMsg > 0){
    int msgheader = recv(clientSocket,(char*)&nlength,6, 0);
    length = ntohl(nlength);//leng value here is in severel thousand size
    char *receivebuffer = new char(length+1);
        bytesReceivedFromClientMsg = recv(clientSocket, receivebuffer, msgheader, 0);
    receivebuffer[length] = 0 ;
    std::cout<<"msg header is :"<<msgheader<<std::endl;
    std::cout<<"msg data is :"<<bytesReceivedFromClientMsg<<std::endl;

        if(bytesReceivedFromClientMsg == SOCKET_ERROR){//some error handling}


推荐答案

您需要为您的网络协议设计一个协议,像SMTP这样的文本协议。你必须读取字符,直到你找到一个终止字符像文本一样的新行协议。

You need a design for your network protocol. There are protocols like SMTP that are text-like protocols. You have to read characters until you find a termination character like the new-line in a text-like protocol.

使用基于消息的协议,您有更好的机会实现高性能协议。您定义一个标头(在您的代码中使用,但未定义)。在标题中,您输入有关长度和可能有关下一条消息类型的信息。然后在邮件正文前面发送标题。在您的示例中,正文是Martin。

With a message based protocol you have better chances for high performance protocol. You define a header (that is used in your code but not defined). In the header you put information about the length and probably about the type of the next message. Then you send the header in front of the message body. The body is "Martin" in your example.

接收器有一个状态header received。当头未完全接收(或根本不接收)时,它将使用头的大小作为块大小。它接收chunksize字节到头变量。当接收到报头完成时,接收机将chunksize设置为在报头中设置的大小,并向有效负载缓冲器接收这么多字节。当这已经完成时,状态标头接收再次为假。

The receiver has a state "header received". When the header is not received complete (or nothting at all) it will use the size of the header as chunk size. It receives chunksize bytes into the header variable. When the header is received complete the receiver sets the chunksize to the sized the is set in the header and receives so many bytes to the payload buffer. When this has been complete the state "header received" is false again.

int receive(socket sock, char * buffer, int chunk_size)
{
    int offset = 0;

    while (chunk_size > 0)
    {
        // add select() here when you have a non-blocking socket.
        int n = recv(sock, buffer+offset, chunk_size);
        // TODO: error handling
        offset += n;
        chunk_size -= n;
    }

    // return amount of received bytes
    return offset;
}

void do_receive(void)
{
    struct {
        int size;
        // other message information
    } header;

    while (true)
    {
        receive(sock, &header, sizeof(header);
        receive(sock, buffer, header.size);
        process_message(buffer, header.size);
    }
}

上面的代码不会通过任何编译器,但它显示的想法..

The code above will not pass any compiler. But it shows the idea..

这篇关于如何提取消息的长度信息,并从TCP字节流中只提取那么多消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆