Сокет linux C ++, который отправляет массив строк (char **) в одном вызове в виде сцепленной строки

0

Я получил массив длинных строк. Я должен отправить их как одну конкатенированную строку в send (int __fd, const void *__buf, size_t __n, int __flags). Я боюсь, что его процессор потребляет процесс для создания единственной конкатенированной строки (char *). Есть ли способ отправить массив строк в голову?

Я не хочу называть send более одного раза для единственной значимой строки, если recv срабатывает более одного раза на принимающей стороне.

Интересно, почему в C/C++ нет стандартизированной расширяемой строковой структуры, такой как связанный список, чтобы читатели могли перейти к следующему буферу в конце буфера. Я хочу, чтобы std::string выполняла это.

  • 3
    взглянуть на writev
  • 0
    Если вы не используете флаги в send вы можете использовать fdopen чтобы создать интерфейс stdio для вашего сокета, а затем просто fwrite потом один за другим в поток.
Показать ещё 8 комментариев
Теги:
string
arrays

2 ответа

3
Лучший ответ

Вам не нужно конкатенировать все строки за один раз. Это не будет очень сильно потребляемым ЦП, так как это произойдет в любом случае, но оно может или не может потреблять много памяти.

Если вы используете флаги в send вы должны определить размер буфера сокета. Объедините свои строки до размера этого буфера, а затем send им один буфер за раз

void send_strings(int sockfd, char ** strings, size_t numstrings, int flags) {
    // get the socket write buffer size
    int buflen;
    unsigned int m = sizeof(bufsize);
    if(getsockopt(sockfd,SOL_SOCKET,SO_SNDBUF,(void *)&buflen, &m)) {
        perror("getsockopt"); return; }

    char buffer[buflen];
    int bufsize = 0;

    while (numstrings--) {
        char * string = *(strings++);
        size_t length = strlen(string);

        // if the string would exceed the buffer
        while (length > buflen - bufsize) {
            memcpy(buffer + bufsize, string, buflen - bufsize);

            length -= buflen - bufsize;
            string += buflen - bufsize;

            // send a full buffer
            send(sockfd, buffer, buflen, flags);
            bufsize = 0;
        }
        // copy the string into the buffer
        memcpy(buffer + bufsize, string, length);
        bufsize += length;
    }
    // send the rest
    if (bufsize) {
        send(sockfd, buffer, bufsize, flags);
    }
}
  • 0
    на принимающей стороне мне нужно использовать recv более одного раза для одной строки. поэтому мне нужно добавить границы и интерпретировать их в конце получения. у меня есть простое решение? thanq
  • 2
    @neckTwi - нет, нет альтернативы протоколу уровня приложения, который может собрать ваши строки из байтового потока TCP в конце recv ().
Показать ещё 4 комментария
0

http://linux.die.net/man/2/send указывает на использование флага MSG_MORE. При установке он инициирует передачу только после send вызова без флага MSG_MORE. Поэтому вызовите send для каждого блока данных с MSG_MORE за исключением последнего блока данных.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню