2014-01-22 3 views
6

Я пишу программу на C++, которая использует c сокеты. Мне нужна функция для получения данных, которые я хотел бы вернуть строку. Я знаю, что это не будет работать:C++ Чтение из сокета в std :: string

std::string Communication::recv(int bytes) { 
    std::string output; 
    if (read(this->sock, output, bytes)<0) { 
     std::cerr << "Failed to read data from socket.\n"; 
    } 
    return output; 
} 

Поскольку функция read() * принимает указатель массива символов для аргумента. Каков наилучший способ вернуть строку здесь? Я знаю, что теоретически могу прочитать данные в массиве символов, а затем преобразовать их в строку, но это кажется мне расточительным. Есть ли способ лучше?

* Я на самом деле не против использовать что-то другое, что read() если есть более подходящий альтернативный

Вот весь код на Pastebin, который должен истечь в неделю. Если у меня нет ответа на то я вновь разместить его: http://pastebin.com/HkTDzmSt

[UPDATE]

Я также попытался с помощью &output[0], но получил выход содержал следующее:

jello! 
[insert a billion bell characters here] 

"желе!" были данные, отправленные обратно в сокет.

+1

c_str() is const, вы не можете этого сделать. просто прочитайте в буфер, затем скопируйте в строку. – billz

+0

@billz Правильно, я отказываюсь от своего предложения. – Borgleader

+0

Это даже правильная форма? Если нет, я должен поступить иначе? – 735Tesla

ответ

4

Вот некоторые функции, которые помогут вам выполнить то, что вы хотите. Предполагается, что вы получите только символ ascii с другого конца сокета.

std::string Communication::recv(int bytes) { 
    std::string output(bytes, 0); 
    if (read(this->sock, &output[0], bytes-1)<0) { 
     std::cerr << "Failed to read data from socket.\n"; 
    } 
    return output; 
} 

или

std::string Communication::recv(int bytes) { 
    std::string output; 
    output.resize(bytes); 

    int bytes_received = read(this->sock, &output[0], bytes-1); 
    if (bytes_received<0) { 
     std::cerr << "Failed to read data from socket.\n"; 
     return ""; 
    } 

    output[bytes_received] = 0; 
    return output; 
} 

При печати строки, обязательно используйте cout << output.c_str() поскольку строка перезаписать operator<< и пропустить нецензурный характер до тех пор, пока не достигнет размера. В конечном итоге вы также можете изменить размер в конце функции до получаемого размера и сможете использовать обычный cout.

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

+0

Я все еще получаю тот же результат, что и в моем последнем комментарии. Интересно то, что кажется, что символы колокола примерно равны длине «джелло!». вычитается из 1024 (параметр, который я использую в настоящее время как 'bytes') – 735Tesla

+0

Если это поможет, я разместил весь свой код на pastebin: http://pastebin.com/HkTDzmSt – 735Tesla

+1

@ 735Tesla Сначала вы должны отправить длину своей строки. Затем, когда вы получаете, вы читаете эту длину сначала, чтобы знать, как много читать дальше. Используя фиксированную длину для приема, вы будете ждать ничего и/или читать мусор в своей строке. –

Смежные вопросы