Невозможно отправить вектор через сокет, даже на одном компьютере (или даже в том же процессе).
Есть две проблемы с этим:
- vector и string поддерживают внутренние указатели на необработанную память. Это исключает отправку вектора <, string> другому процессу
- dtors вектора и строки захотят удалить этот указатель. Операции с сокетами сделают memcpy для вашего объекта (включая значения необработанных указателей), и вы получите двойное удаление.
Итак, правило таково: чтобы отправлять объекты через сокет, он должен быть в состоянии memcpy'd. Есть несколько способов сделать это
- Сериализация вектора Такие вещи, как ICE, хороши для генерации этих сериализаций http://www.zeroc.com/ Они имеют очевидные издержки
- Создайте что-нибудь с тем же интерфейсом, что и вектор и строка, но с возможностью memcpy'd
- Создание версий только для чтения того, что выглядит как вектор. Сторона отправки может быть обычным вектором, сторона recv может повторно интерпретировать_cast буфер recv в качестве реализации только для чтения
Номер 2 вообще очень сложно сделать, но с некоторыми ограничениями это возможно. Для высокопроизводительных приложений вы не собираетесь использовать вектор в любом случае.
Номер 3 применяется для всех вариантов использования, в которых читатель редко изменяет содержимое буфера recv. Если читателю не нужны итераторы произвольного доступа, и он может работать с ForwardIterators, сериализация довольно проста: выделить один буфер, который может содержать все строки, плюс и целое число для каждой, обозначая длину плюс одно целое число для размера вектора.
Результат может быть reinterpret_cast'd для определенной пользователем структуры, которая является коллекцией только для чтения строк только для чтения. Так что без особых проблем вы можете по крайней мере получить O (1) на стороне чтения.
Чтобы получить O (1) на отправляющей стороне, вам нужно использовать метод 2. Я сделал это, зная, что мое приложение никогда не будет использовать больше, чем строки длины X, и что вектор никогда не будет содержать более Y предметов. Хитрость в том, что для исправления емкости мне никогда не придется идти в кучу памяти. Недостатком является то, что вы отправляете всю емкость каждой строки, а не только то, что было использовано. Однако во многих случаях просто отправлять все гораздо быстрее, чем пытаться сжать его, особенно если вы находитесь на одной машине - в этом случае вы можете просто поместить эту структуру в общую память и уведомить приложение recv о том, что оно просто ищет.
Возможно, вы захотите взглянуть на boost interprocess, чтобы получить больше идей о том, как создавать контейнеры, которые можно переносить через сокеты без сериализации.