LINUX.ORG.RU

Сокеты - Несовпадение длины пакетов MJPEG при чтении

 , , ,


0

1

Есть сервер который читает по 255 байт MJPEG поток и сразу их же по 255 байт отправляет на заданный ip (другой сервер)

std::stringstream requestQuery;
requestQuery << "GET /axis-cgi/mjpg/video.cgi?resolution=320x240 HTTP/1.1\r\n"
             << "Host: 88.53.197.250\r\n"
             << "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
             << "\r\n\r\n";
std::string request = requestQuery.str();

// sock - источник MJPEG
if (send(sock, request.c_str(), request.length(), 0) != (int)request.length()) {
    std::cout << "Error sending request." << std::endl;
    exit(1);
}

char buffer[256];
char cur2;
while (1) {
    bzero(buffer,256);
    size_t n = read(sock,buffer,255);
    if (n < 0)
        printf("ERROR reading from socket\n");
    size_t n2 = write(sockServ,buffer,255);  // sockServ - приемник MJPEG
}

Данные приходят, я их вижу они выглядят так

HTTP/1.1 200 OK\r\n
Cache-Control: no-cache\r\n
Pragma: no-cache\r\n
Expires: Thu, 01 Dec 1994 16:00:00 GMT\r\n
Connection: close\r\n
Content-Type: multipart/x-mixed-replace; boundary=--myboundary\r\n
\r\n
--myboundary\r\n
Content-Type: image/jpeg\r\n
Content-Length: 8530\r\n
\r\n
(тут пошли данные)

На заданном IP есть другой сервер.

Я открываю сокет, жду подключения (accept) и пытаюсь считать данные. Вначале считываю общий заголовок, Потом заголовок первого маркера "--myboundary" до значения длины, потом саму длину

bzero(buffer,512);
n = read(newsockfd,buffer,185); // общий заголовок
if (n < 0) error("ERROR reading from socket");
// printf("%s\n",buffer);

while(1) {
    bzero(buffer, 512);
    n = read(newsockfd, buffer, 56); // заголовок с --myboundary
    printf("HEADER:\n",buffer);
    printf("%s\n",buffer);// вывожу заголовок
    if (n < 0) error("ERROR reading from socket");
    bzero(filesizetext,20);
    int i = 0;
    while(1) {
        n = read(newsockfd, &ch, 1); // по одному символу до конца строки считываю значение Content-Length
        if (n < 0) error("ERROR reading from socket");
        if (ch == '\r')
            break;
        filesizetext[i] = ch;
        i++;
    }
    int currFileSize = atoi(filesizetext); // преобразую Content-Length в число
    n = read(newsockfd, buf, currFileSize); // считываю Content-Length байт
    if (n < 0) error("ERROR reading from socket");

	// идем дальше, снова считывать заголовок  с --myboundary
}

Когда доходим до «идем дальше, снова считывать заголовок с --myboundary» Вместо заголовка выводятся кракозябры - значит данные еще не кончились, и мы считали раньше чем нужно.

1) Чем может объясняться несовпадиние длины данных?

2) Можно ли с писать в сокет по 512 байт, а читать переменное количество?


read() не обязан вычитывать весь буфер за один вызов. Проверяй в цикле пока все данные не прочитаешь.

roof ★★ ()
Ответ на: комментарий от roof

Господи, действительно помогло.

Вот этот участок кода на сервере1

bzero(buffer,256);
size_t n = read(sock,buffer,255);
if (n < 0)
    printf("ERROR reading from socket\n");
 size_t n2 = write(sockServ,buffer,255);
 

должен быть переписан

 size_t n2 = write(sockServ,buffer,n);
JANB ()
Ответ на: комментарий от JANB

Ну и везде в остальных участках нужно проверять количество считанных байт

JANB ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.