Я относительно новичок в сетевом программировании и у меня есть несколько вопросов о передовых практиках непрерывной быстрой передачи данных (изображений) между клиентом и сервером с помощью Boost Asio.Важный момент, мы не можем применять сжатие, которое снижает качество изображения.Мы используем выделенную сеть (54 Мбит) без трафика, кроме нашего.Нам рекомендовали использовать Boost Asio, так как он, кажется, подходит для наших нужд.Тем не менее, поскольку Boost является мощным средством, это сложно для неопытных (Boost) разработчиков, таких как я.
Мы хотим разработать как можно более простой инструмент, который бы непрерывно передавал непрерывно данные изображения между клиентом и пользователем.сервер.В основном это потоковое.Мы бы предпочли использовать TCP, но если бы у нас был значительный прирост производительности с UDP, мы бы не возражали против потери пакетов данных время от времени.
Данные представляют собой беззнаковый буфер символов (640x480px = 307200 байт = 2,34).MBit, монохромный).
Я начал с учебников по Asio и поиграл с проектами sync, async, UDP, TCP.На данный момент я могу отправлять данные с ~ 10fps, ~ 0,1 мс на изображение с TCP и ~ 13fps с UDP.Это слишком медленно.Я ожидал, что отправка 2,4 Мбит в сети 54 Мбит будет быстрее.
Сегодня я не использую сериализацию, архивирование, сжатие (zip) и т. Д. Моих данных.Я думаю, что это улучшит передачу, но мне интересно, должен ли я уладить свои ожидания и / или должен ли я полностью изменить свой подход?
Является ли сериализация данных подходом для потоковой передачи данных сAsio?Сжатие почтового индекса улучшит передачу вероятно значительно?Существуют ли альтернативные подходы или структуры?
Пример кода TCP-сервера
// sends data whenever it receives a request by the client
int main(int argc, char* argv[])
{
init_image_buffer();
try
{
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 13));
for (;;)
{
tcp::socket socket(io_service);
acceptor.accept(socket);
boost::system::error_code ignored_error;
boost::asio::write(socket, boost::asio::buffer(image_buffer),
boost::asio::transfer_all(), ignored_error);
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
Пример кода TCP-клиента
Я понимаю, что этот код не является оптимальным.Но я не мог понять, как оставаться на связи и запрашивать новые данные с помощью такого подхода.
int main(int argc, char* argv[])
{
Clock clock;
clock.Initialise();
float avg = 0.0;
float min = 1000000.0;
float max = 0.0;
float time = 0.0;
// sending multiple images
for(int j=0;j<IMAGE_COUNT;j++){
try
{
clock.GetTime();
if (argc != 2)
{
std::cerr << "Usage: client <host>" << std::endl;
return 1;
}
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query(argv[1], 13);
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
tcp::socket socket(io_service);
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
socket.close();
socket.connect(*endpoint_iterator++, error);
}
if (error)
throw boost::system::system_error(error);
// we read all received data but do NOT save them into a dedicated image buffer
for (;;)
{
boost::array<unsigned char, 65536> temp_buffer;
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(temp_buffer), error);
if (error == boost::asio::error::eof)
break; // Connection closed cleanly by peer.
else if (error)
throw boost::system::system_error(error); // Some other error.
}
time = clock.GetTime();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
// calculate some time transfer statistics
avg+=time;
if(time < min) min = time;
if(time > max) max = time;
}
std::cout << "avg: " << avg/(float)IMAGE_COUNT << " freq: " << 1.0/(avg/(float)IMAGE_COUNT) << std::endl;
std::cout << "min: " << min << " max: " << max << std::endl;
return 0;
}