<bdo id='QWjmv'></bdo><ul id='QWjmv'></ul>
  1. <i id='QWjmv'><tr id='QWjmv'><dt id='QWjmv'><q id='QWjmv'><span id='QWjmv'><b id='QWjmv'><form id='QWjmv'><ins id='QWjmv'></ins><ul id='QWjmv'></ul><sub id='QWjmv'></sub></form><legend id='QWjmv'></legend><bdo id='QWjmv'><pre id='QWjmv'><center id='QWjmv'></center></pre></bdo></b><th id='QWjmv'></th></span></q></dt></tr></i><div id='QWjmv'><tfoot id='QWjmv'></tfoot><dl id='QWjmv'><fieldset id='QWjmv'></fieldset></dl></div>

  2. <small id='QWjmv'></small><noframes id='QWjmv'>

    1. <tfoot id='QWjmv'></tfoot>

      <legend id='QWjmv'><style id='QWjmv'><dir id='QWjmv'><q id='QWjmv'></q></dir></style></legend>

      从 C/C++ 中的 TCP 套接字读取的正确方法是什么?

      What is the correct way of reading from a TCP socket in C/C++?(从 C/C++ 中的 TCP 套接字读取的正确方法是什么?)
        <tbody id='CYElx'></tbody>

        1. <i id='CYElx'><tr id='CYElx'><dt id='CYElx'><q id='CYElx'><span id='CYElx'><b id='CYElx'><form id='CYElx'><ins id='CYElx'></ins><ul id='CYElx'></ul><sub id='CYElx'></sub></form><legend id='CYElx'></legend><bdo id='CYElx'><pre id='CYElx'><center id='CYElx'></center></pre></bdo></b><th id='CYElx'></th></span></q></dt></tr></i><div id='CYElx'><tfoot id='CYElx'></tfoot><dl id='CYElx'><fieldset id='CYElx'></fieldset></dl></div>
              <bdo id='CYElx'></bdo><ul id='CYElx'></ul>
            • <tfoot id='CYElx'></tfoot>
                <legend id='CYElx'><style id='CYElx'><dir id='CYElx'><q id='CYElx'></q></dir></style></legend>

                <small id='CYElx'></small><noframes id='CYElx'>

                本文介绍了从 C/C++ 中的 TCP 套接字读取的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                这是我的代码:

                // Not all headers are relevant to the code snippet.
                #include <stdio.h>
                #include <sys/types.h>
                #include <sys/socket.h>
                #include <netinet/in.h>
                #include <netdb.h>
                #include <cstdlib>
                #include <cstring>
                #include <unistd.h>
                
                char *buffer;
                stringstream readStream;
                bool readData = true;
                
                while (readData)
                {
                    cout << "Receiving chunk... ";
                
                    // Read a bit at a time, eventually "end" string will be received.
                    bzero(buffer, BUFFER_SIZE);
                    int readResult = read(socketFileDescriptor, buffer, BUFFER_SIZE);
                    if (readResult < 0)
                    {
                        THROW_VIMRID_EX("Could not read from socket.");
                    }
                
                    // Concatenate the received data to the existing data.
                    readStream << buffer;
                
                    // Continue reading while end is not found.
                    readData = readStream.str().find("end;") == string::npos;
                
                    cout << "Done (length: " << readStream.str().length() << ")" << endl;
                }
                

                正如您所知,它有点 C 和 C++.BUFFER_SIZE 是 256 - 我应该增加大小吗?如果是这样,该怎么办?重要吗?

                It's a little bit of C and C++ as you can tell. The BUFFER_SIZE is 256 - should I just increase the size? If so, what to? Does it matter?

                我知道如果由于任何原因没有收到end",这将是一个无限循环,这很糟糕 - 所以如果你能提出更好的方法,也请这样做.

                I know that if "end" is not received for what ever reason, this will be an endless loop, which is bad - so if you could suggest a better way, please also do so.

                推荐答案

                在不了解您的完整应用程序的情况下,很难说出解决问题的最佳方法是什么,但一种常见的技术是使用以固定长度字段,表示消息其余部分的长度.

                Without knowing your full application it is hard to say what the best way to approach the problem is, but a common technique is to use a header which starts with a fixed length field, which denotes the length of the rest of your message.

                假设您的标头仅由一个 4 字节的整数组成,它表示消息其余部分的长度.然后只需执行以下操作.

                Assume that your header consist only of a 4 byte integer which denotes the length of the rest of your message. Then simply do the following.

                // This assumes buffer is at least x bytes long,
                // and that the socket is blocking.
                void ReadXBytes(int socket, unsigned int x, void* buffer)
                {
                    int bytesRead = 0;
                    int result;
                    while (bytesRead < x)
                    {
                        result = read(socket, buffer + bytesRead, x - bytesRead);
                        if (result < 1 )
                        {
                            // Throw your error.
                        }
                
                        bytesRead += result;
                    }
                }
                

                然后在代码中

                unsigned int length = 0;
                char* buffer = 0;
                // we assume that sizeof(length) will return 4 here.
                ReadXBytes(socketFileDescriptor, sizeof(length), (void*)(&length));
                buffer = new char[length];
                ReadXBytes(socketFileDescriptor, length, (void*)buffer);
                
                // Then process the data as needed.
                
                delete [] buffer;
                

                这里有几个假设:

                • 发送方和接收方的整数大小相同.
                • 发送方和接收方的字节序相同.
                • 您可以控制双方的协议
                • 发送消息时,您可以预先计算长度.

                因为想要明确知道您通过网络发送的整数的大小是很常见的,所以在头文件中定义它们并明确使用它们,例如:

                Since it is common to want to explicitly know the size of the integer you are sending across the network define them in a header file and use them explicitly such as:

                // These typedefs will vary across different platforms
                // such as linux, win32, OS/X etc, but the idea
                // is that a Int8 is always 8 bits, and a UInt32 is always
                // 32 bits regardless of the platform you are on.
                // These vary from compiler to compiler, so you have to 
                // look them up in the compiler documentation.
                typedef char Int8;
                typedef short int Int16;
                typedef int Int32;
                
                typedef unsigned char UInt8;
                typedef unsigned short int UInt16;
                typedef unsigned int UInt32;
                

                这会将上面的内容更改为:

                This would change the above to:

                UInt32 length = 0;
                char* buffer = 0;
                
                ReadXBytes(socketFileDescriptor, sizeof(length), (void*)(&length));
                buffer = new char[length];
                ReadXBytes(socketFileDescriptor, length, (void*)buffer);
                
                // process
                
                delete [] buffer;
                

                我希望这会有所帮助.

                这篇关于从 C/C++ 中的 TCP 套接字读取的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                相关文档推荐

                What is inside .lib file of Static library, Statically linked dynamic library and dynamically linked dynamic library?(静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么?)
                How do I load a C DLL from the SXS in Python?(如何从 Python 中的 SXS 加载 C DLL?)
                Can Cython code be compiled to a dll so C++ application can call it?(Cython 代码可以编译成 dll 以便 C++ 应用程序可以调用它吗?)
                Delay Loading DLLs(延迟加载 DLL)
                Throwing C++ exceptions across DLL boundaries(跨 DLL 边界抛出 C++ 异常)
                Loading a dll from a dll?(从 dll 加载 dll?)
                    <tbody id='Knk97'></tbody>
                  <i id='Knk97'><tr id='Knk97'><dt id='Knk97'><q id='Knk97'><span id='Knk97'><b id='Knk97'><form id='Knk97'><ins id='Knk97'></ins><ul id='Knk97'></ul><sub id='Knk97'></sub></form><legend id='Knk97'></legend><bdo id='Knk97'><pre id='Knk97'><center id='Knk97'></center></pre></bdo></b><th id='Knk97'></th></span></q></dt></tr></i><div id='Knk97'><tfoot id='Knk97'></tfoot><dl id='Knk97'><fieldset id='Knk97'></fieldset></dl></div>

                  <small id='Knk97'></small><noframes id='Knk97'>

                  • <legend id='Knk97'><style id='Knk97'><dir id='Knk97'><q id='Knk97'></q></dir></style></legend>
                    <tfoot id='Knk97'></tfoot>

                          <bdo id='Knk97'></bdo><ul id='Knk97'></ul>