这是我的代码:
// 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 - 我应该增加大小吗?如果是这样,该怎么办?有关系吗?
我知道如果出于某种原因没有收到“end”,这将是一个无限循环,这很糟糕 - 所以如果你能提出更好的方法,也请这样做。
最佳答案
在不了解您的完整应用程序的情况下,很难说解决问题的最佳方法是什么,但一种常见的技术是使用以固定长度字段开头的 header ,该字段表示消息其余部分的长度.
假设您的 header 仅包含一个 4 字节整数,表示您的消息其余部分的长度。然后只需执行以下操作。
// 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;
这做了一些假设:
由于通常希望明确知道您通过网络发送的整数的大小,因此在头文件中定义它们并明确使用它们,例如:
// 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;
这会将上面的内容更改为:
UInt32 length = 0;
char* buffer = 0;
ReadXBytes(socketFileDescriptor, sizeof(length), (void*)(&length));
buffer = new char[length];
ReadXBytes(socketFileDescriptor, length, (void*)buffer);
// process
delete [] buffer;
我希望这会有所帮助。
https://stackoverflow.com/questions/666601/