Я разрабатываю клиент-серверное приложение, которое делится некоторыми изображениями с камеры. Общий цикл:
- Клиент захватывает изображение с камеры и сжимает его в двоичное изображение. После этого он отправляет его на сервер
- Сервер точно знает, насколько большой буфер (640 * 480/8 байт), поэтому он может получить изображение дыры только с одним recv-вызовом. Следующий recv-вызов получит второе изображение и так далее
- После получения изображения сервер работает с изображением и затем отправляет другое изображение обратно клиенту. Но вот проблема: изображение сжато в формате 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) Я думал, что это прекратит прием (потому что если часть меньше 512 байт, она должна быть концом) Но мой recvBuf содержит только последние байты.
Возможно, возможно, что я не понимаю, что такое дырочный Winsock, но я думал, что recvBuf будет содержать буфер дырок, который я получил. Это неправильно? Как получить дыру полученный буфер без закрытия соединения?