gpt4 book ai didi

c - Winsock:如何在不关闭连接的情况下停止发送/接收

转载 作者:太空宇宙 更新时间:2023-11-04 01:42:08 26 4
gpt4 key购买 nike

我开发了一个共享一些相机图像的客户端/服务器应用程序。一般的周期是:

  1. 客户端捕获相机图像并将其压缩为二进制图像。然后将其发送到服务器
  2. 服务器确切地知道缓冲区有多大(640*480/8 字节),因此他只需要一次接收调用就可以接收到洞图像。下一个 recv-call 将获得第二张图片,依此类推
  3. 服务器收到图像后处理该图像,然后将另一幅图像发送回客户端。但问题是:图像是 jpeg 压缩的,因此客户端不知道文件大小,无法像具有固定缓冲区长度的服务器那样接收图像。

我认为如果服务器在发送图像后关闭连接,那将不是问题。但我不想关闭连接,因为在下一个周期中我将通过同一连接发送下一张图像。

我的问题是:如何在不关闭连接的情况下告诉客户端服务器发送了孔洞图像?

这是一些代码:(客户端将二进制图像发送给服务器)

void sendToServer(char* sendbuf, int sendbuflen) {
int iResult = send(ConnectSocket, sendbuf, sendbuflen, 0);
if (iResult == SOCKET_ERROR) {
(*errCallbackFunc)("Sending image error", -1);
}
}

(服务器只用一个函数调用接收图像 - recbuflen = 640*480/8)

int receiveCameraImages(ARUint8* dataPtr) {
int iResult;

iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
if ((*(recvbuf+0)) != 'U' || (*(recvbuf+((xsize*ysize/8)-1))) != 'U')
return RECEIVING_INCOMPLETE;

convertBWChartoBGR(recvbuf, dataPtr, recvbuflen);

return RECEIVING_SUCCEEDED;
} else if (iResult == 0) {
(*errCallbackFunc)("Connection closing", -1);
return RECEIVING_CONN_CLOSED;
}
else {
(*errCallbackFunc)("recv failed", WSAGetLastError());
return RECEIVING_ERROR;
}
}

(现在服务器处理图像并发送回另一个 jpeg 压缩图像)

int sendObjectImage(ARUint8* dataPtr, int bufLen) {
int iResult;

/* send the openGLBuffer back to the client */
iResult = send(ClientSocket, dataPtr, bufLen, 0);
if (iResult == SOCKET_ERROR) (*errCallbackFunc)("send openglbuffer back to client failed", WSAGetLastError());
}

(而且客户端不知道缓冲区有多大所以接收了512Byte的部分)

int receiveFromServer(ARUint8* dataPtr) {
int iResult, returnBufLen = 0;
int recvBufLen = DEFAULT_BUFFER_LEN;
ARUint8 recvBuf[DEFAULT_BUFFER_LEN];

/* receive openGL buffer */
do {
iResult = recv(ConnectSocket, recvBuf, recvBufLen, 0);
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);
returnBufLen += iResult;
}
else if (iResult == 0)
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
} while (iResult >= DEFAULT_BUFFER_LEN);

dataPtr = recvBuf;

return returnBufLen;
}

while (iResult >= DEFAULT_BUFFER_LEN) 我认为它会停止接收(因为如果一个部分小于 512Bytes 它必须是结束)。但是我的 recvBuf 只包含最后一个字节。

也许我不了解 hole winsock 的东西,但我认为 recvBuf 将包含我收到的 hole 缓冲区。那是错的吗?如何在不关闭连接的情况下获取空洞接收缓冲区?

最佳答案

  1. 不要依赖对 recv()send() 的单次调用能够运行完成并处理您请求的数据量.您必须准备好在一个循环中多次运行它们,直到传输了所需数量的数据。

  2. 如果服务器想要返回未知长度的图像,只需先发送长度,使用明确定义的格式(例如网络字节顺序的 32 位整数)。然后客户端可以进行两次单独的接收,一次接收大小,一次接收数据。同样,这并不意味着它可以简单地进行两次 recv() 调用。

关于c - Winsock:如何在不关闭连接的情况下停止发送/接收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3769706/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com