我正在读取从Java客户端发送到Sockets的C ++服务器的图像URL。当检测到char缓冲区[]中有空字符时,服务器停止通过recv()读取,如下面的代码所示:
void * SocketServer::clientController(void *obj)
{
// Retrieve client connection information
dataSocket *data = (dataSocket*) obj;
// Receive data from a client step by step and append data in String message
string message;
int bytes = 0;
do
{
char buffer[12] = {0};
bytes = recv(data->descriptor, buffer, 12, 0);
if (bytes > 0) // Build message
{
message.append(buffer, bytes);
cout << "Message: " << message << endl;
}
else // Error when receiving it
cout << "Error receiving image URL" << endl;
// Check if we are finished reading the image link
unsigned int i = 0;
bool finished = false;
while (i < sizeof(buffer) / sizeof(buffer[0]) && !finished)
{
finished = buffer[i] == '\0';
i++;
}
if (finished)
break;
}
while (bytes > 0);
cout << message << endl;
close(data->descriptor);
pthread_exit(NULL);
}
是否有更好,更优雅的方式来做到这一点?
我读到了关于首先发送URL大小的内容,但我不确切知道如何使用它来停止recv()。我想这是通过计算收到的字节直到达到URL的大小来完成的。那一刻,我们应该读完了。
另一种方法可能是关闭Java套接字,以便recv()返回-1并且循环将完成。但是,考虑到我的Java客户端等待来自C ++服务器的响应,关闭套接字然后重新打开它似乎不合适。
谢谢你, 埃克托
答案 0 :(得分:0)
除了你的缓冲区有一个不寻常的大小(一个通常选择2的幂,所以8,16,32,...),它看起来有点小你的意图,你的方法对我来说似乎很好:< / p>
我假设你的java客户端将发送一个空终止字符串然后等待,我。即特别是它不会发送任何进一步的数据。因此,在收到0字符之后,无论如何都不会有任何数据接收,所以不需要为recv隐式显式的事情而烦恼(recv通常只返回可用的数据,即使小于缓冲区可以消耗的。)
请注意,您使用0初始化缓冲区,因此如果检查整个缓冲区(而不是范围[buffer, buffer + bytes
),则可能会检测到误报(如果在第一次迭代中收到少于12个字符) )!但是,无论如何,检测0字符可以更优雅地完成:
if(std::find(buffer, buffer + bytes, 0) < buffer + bytes)
{
// found the 0 character!
break;
}