Я написал сервер на C ++ и для отправки сообщений установил следующий поток:

void *send(void* v)
{
    string m="";
    while(true)
    {
        std::cin >> m;
        write(socketfd, static_cast<void*>(&m), m.length()+1);
    }
}

Для чтения сообщений я написал следующий код:

public void recieve() throws IOException{
    while (true){
        if(input.hasNext()){
            viewText.setText(viewText.getText() + "\nSever: "+input.nextLine());
        }
    }
}

@Override
public void run() {
    try {
        recieve();
        socket.close();
    }
    catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

Когда я пишу в переменную M и нажимаю Enter, ничего не происходит. Но когда я закрываю сервер, все значения m, которые я написал ранее, печатаются как одна строка.

Прошу прощения за неправильный английский. танки

2
Ido Ikar 7 Сен 2016 в 15:21

3 ответа

Лучший ответ

Не зная тип input в вашем коде Java, имя метода nextLine() предполагает, что он будет читать всю строку. Строка - это последовательность символов, которая заканчивается символом новой строки. С другой стороны, символ новой строки не будет сохраняться через std::cin >> m;, поэтому все данные до завершения отправляющей стороны будут рассматриваться как одна строка.

Чтобы отправить несколько строк, вы должны использовать другой способ, например std::getline(std::cin, m);, чтобы читать ввод и добавлять символы новой строки, если способ их отбрасывает.

4
MikeCAT 7 Сен 2016 в 12:27
std::cin >> m;

Будет читать только до первого экземпляра пробела или новой строки, если написано только одно слово:

input.nextLine()

Читается, пока не будет введена новая строка, и пробелы не оканчиваются. Чтобы сделать эквивалент в C ++, вам необходимо использовать getline(std::cin, m) вот так (не забудьте включить <string>):

getline(std::cin, input)
1
Arnav Borborah 7 Сен 2016 в 12:32
string m="";

m - это класс под названием std::string.

static_cast<void*>(&m),

&m - это адрес структуры std::string. Это не адрес фактической строки, которую представляет этот класс. Вам нужно получить фактическое содержимое строкового класса и записать его в сокет:

write(socketfd, m.c_str(), m.length()+1);

Это слишком упрощенный пример, но вы можете думать о std::string как о классе, который выглядит следующим образом:

class std::string {

    char *data;
    size_t length;

    // ...
};

Запись физического адреса этого указателя и другого внутреннего содержимого строкового класса в сокет не дает ничего полезного. Вам необходимо получить фактические строковые данные.

4
Sam Varshavchik 7 Сен 2016 в 12:23