Как отправить большую строку в Winsock с помощью C ++ с клиента на сервер - PullRequest
0 голосов
/ 07 ноября 2019

Я пишу сервер-клиентское приложение, использующее Winsock на c ++ для отправки файла построчно, и у меня проблема с отправкой огромной строки. Размер строки очень большой.

Для получения сообщения от клиента сервером я использую следующий код.

int result;
char message[200];

while (true)
{
    recv(newSd, (char*)&message, sizeof(message), 0);

    cout << "The Message from client: " << message << ";";
}

Приведенный выше код работает нормально, если я отправляю небольшую длинусообщение. Но я хотел отправить неизвестный размер строк в файле.

Как отправить большую неизвестную строку вместо символьного сообщения [200];

1 Ответ

0 голосов
/ 07 ноября 2019

TCP - это поток байтов, он ничего не знает о сообщениях, строках или о чем-либо подобном. Когда вы отправляете данные по TCP, все, что он знает, это необработанные байты, а не то, что представляют байты. Вы несете ответственность за реализацию протокола обмена сообщениями поверх TCP, чтобы каким-либо значимым образом разграничить данные, чтобы получатель мог знать, когда данные завершены. Есть два способа сделать это:

  • отправить длину данных перед отправкой фактических данных. Получатель сначала читает длину, а затем читает, сколько байтов говорит длина.

  • отправляет уникальный терминатор после отправки данных. Убедитесь, что терминатор никогда не появляется в данных. Затем получатель может читать, пока не получен терминатор.

Вы не обрабатываете ни один из них в вашем recv() коде, поэтому я подозреваю, что вы не обрабатываете ни один из них в вашем *Код 1014 * тоже (который вы не показывали).

Поскольку вы отправляете текстовый файл, вы можете:

  • отправить размер файла, например:в uint32_t или uint64_t (в зависимости от размера файла), затем отправьте необработанные байты файла.

  • отправьте каждую текстовую строку отдельно как есть, завершаетсяCRLF или bare-LF разрыв строки после каждой строки, а затем отправка последнего терминатора после последней строки.

Вы также игнорируете возвращаемое значение recv(), которое сообщаетВы, сколько байтов было фактически получено. Он может и обычно возвращает меньше байтов, чем запрошено, поэтому вы должны быть готовы к многократному вызову recv(), обычно в цикле, для полного получения данных. То же самое с send().

...