Приложение работает с тремя сокетами, отправляющими данные на один php-скрипт HTTP-сервера:
управляющий сокет - постит присутствие клиента, получает ответы с запросами на активацию/деактивацию остальных двух сокетов. Есть команды send и recv
сокет вебкамеры - стримит кадры с вебки по запросу. Только send
сокет рабочего стола - стримит скриншоты по запросу. Только send
С 1-м проблем нет вообще - если не отправил или не получил - без каких либо ожиданий пересоздаёт подключение и работает дальше. Проблема со 2-м:
DWORD WINAPI NetExCamera(LPVOID){
unsigned short StreamRate = 50;
unsigned int OperationStartTime;
string Header = "POST " + STREAM_URI + " HTTP/1.1\r\nHost: " + STREAM_Host + /*другие параметры*/"\r\nContent-Type: image/jpeg\r\nContent-Transfer-Encoding: binary\r\nContent-Length: ";
CAMERA.Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (connect(CAMERA.Socket, (SOCKADDR*)(&Target), sizeof(Target)) == 0){
cout << "Camera socket connected!\n";
}
while(CAMERA.Stream){
OperationStartTime = GetTickCount();
CameraFrameSize = WebCam->GetFrameSize();
CameraFrameBuffer = (unsigned char *)realloc(CameraFrameBuffer, CameraFrameSize);
compress_image_to_jpeg_file_in_memory(CameraFrameBuffer, CameraFrameSize, RES_X ,RES_Y, 3, WebCam->CaptureFrame(), CameraCompressor);
CameraFrame = string(reinterpret_cast<char*>(CameraFrameBuffer), CameraFrameSize);
stringstream SendBuffer;
SendBuffer << Header << CameraFrame.size() << "\r\n\r\n" << CameraFrame;
// Sending data...
cout << "Sending data...\n";
if (send(CAMERA.Socket, &SendBuffer.str()[0], SendBuffer.str().size(), 0) < 0){
cout << "Camera socket send error: " << WSAGetLastError() << endl;
CameraFrame = "";
closesocket(CAMERA.Socket);
CAMERA.Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (connect(CAMERA.Socket, (SOCKADDR*)(&Target), sizeof(Target)) == 0){
cout << "Camera socket connected!\n";
}
}
cout << "Send OK!\n";
while(OperationStartTime + StreamRate > GetTickCount()){
if (!CAMERA.Stream){break;}
Sleep(1);
}
}
closesocket(CAMERA.Socket);
cout << "Camera socket disconnected!\n";
return 0;
}
Как видно из кода, сокет работает в своём потоке, более того send вроде по умолчанию не блокирующий, но в один момент, спустя 8-11 секунд с начала передачи данных, консольный вывод замирает на строчке cout << "Sending data...\n";
, потом секунд через 15-20 "оттаивает", естественно сервер его уже откинул (на apache KeepAliveTimeout 5), и после этой задержки уже выходит cout << "Camera socket send error: " << WSAGetLastError() << endl;
с кодом ошибки WSA 10054.
Такое ощущение, что у send есть какой-то невидимый буфер, который переполняется и отправка замирает. Размеры кадров с камеры 6-10 кб. Третий сокет работает по той же схеме, только частота у него не 20 кадров в секунду, а 2 - с ним никаких зависаний не происходит.
Проблема по какой-то причине не возникает на Windows 8.1 x64 на localhost-е, а на 7-ке вот такая беда.
В чём реально может быть причина и как это исправить?
В ответ на каждый HTTP POST запрос, которым вы шлете кадр с камеры, сервер шлет ответ.
Эти ответы надо читать (они переполняют буфер и http сервер, подвисая на очередном send, не в состоянии прочесть ваш очередной запрос).
Вот так обе стороны и висят, каждая на своем send.
Кроме того, возможна ситуация, когда ваш send отошлет не все данные. Поэтому его нужно выполнять в цикле, пока все SendBuffer.str().size()
байт не будут отосланы.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Есть MFC проект на C++, и word 2007, надо сгенерировать новый word документ без сторонних библиотек, каким образом можно это сделать ?
У меня на QMainWindow находятся QGraphicsView и QHBoxLayoutНеобходимо, чтобы при расширении окна, QHBoxLayout отъезжал вправо, а QGraphicsView оставался на месте