Я получил массив длинных строк. Я должен отправить их как одну конкатенированную строку в send (int __fd, const void *__buf, size_t __n, int __flags)
. Я боюсь, что его процессор потребляет процесс для создания единственной конкатенированной строки (char *). Есть ли способ отправить массив строк в голову?
Я не хочу называть send
более одного раза для единственной значимой строки, если recv
срабатывает более одного раза на принимающей стороне.
Интересно, почему в C/C++
нет стандартизированной расширяемой строковой структуры, такой как связанный список, чтобы читатели могли перейти к следующему буферу в конце буфера. Я хочу, чтобы std::string
выполняла это.
Вам не нужно конкатенировать все строки за один раз. Это не будет очень сильно потребляемым ЦП, так как это произойдет в любом случае, но оно может или не может потреблять много памяти.
Если вы используете флаги в 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);
}
}
recv
более одного раза для одной строки. поэтому мне нужно добавить границы и интерпретировать их в конце получения. у меня есть простое решение? thanq
http://linux.die.net/man/2/send указывает на использование флага MSG_MORE
. При установке он инициирует передачу только после send
вызова без флага MSG_MORE
. Поэтому вызовите send
для каждого блока данных с MSG_MORE
за исключением последнего блока данных.
writev
send
вы можете использоватьfdopen
чтобы создать интерфейсstdio
для вашего сокета, а затем простоfwrite
потом один за другим в поток.