Как определить конец чтения
У меня есть простой C-сервер и Java-клиент. Я отправляю текстовый файл построчно с сервера на клиент:
do {
send(sockfd, line, strlen(line), 0);
printf("%s\n", line);
} while ((fgets(line, 100, fp)) != NULL);
и прочитайте его в Java-клиенте с помощью:
Client.getCl().getInputStream().read(inmsg);
do{
decoded = new String(inmsg, "UTF-8");
System.out.println(decoded);
}while(Client.getCl().getInputStream().read(inmsg) > 0);
Моя проблема в том, что я не знаю, как отправить "конец чтения" с сервера на клиент. Клиент зависает при последнем прочтении. Я знаю этот метод read()
возвращает целое число с числом получаемых байтов и -1, когда нечего читать, и 0, если длина буфера равна нулю. Единственное решение, которое вернуло -1 клиенту, - закрыть сокет на стороне сервера, но я не могу это использовать. Также я попробовал следующее:
1) Отправьте длину 0 в конце метода отправки, чтобы сообщить клиенту, что длина равна нулю:
send(sockfd, NULL, NULL, 0);
2) Определите флаги и отправьте:
#define MSG_FIN 0x200
#define MSG_EOR 0x0080
и снова с обоими флагами:
send(sockfd, NULL, NULL, MSG_FIN);
send(sockfd, NULL, NULL, MSG_EOR);
Кто-нибудь, пожалуйста, помогите, что я здесь делаю не так? Спасибо
2 ответа
Если вы хотите отправлять прерывистые данные через один и тот же TCP-сокет, вам необходимо закодировать границы информации, которую вы отправляете, в данных, которые вы отправляете. Примером этого является отправка "пакетов" данных с префиксом длины, чтобы получатель пакета считывал с сокета столько байтов, сколько говорит префикс длины.
У вас две проблемы с вашим читателем. Вы предполагаете, что всегда будете читать полный буфер. Вы не можете принять это, если только вы не читаете только один байт за раз. Вы также предполагаете, что всегда будете читать целые многобайтовые символы, это вряд ли будет верно, если вы никогда не используете многобайтовые символы.
Поскольку вы пишете текст, я предлагаю вам отправлять новые строки между сообщениями и читать поток как текст.
BufferedReader br = new BufferedReader(new InputStreamReader(
Client.getCl().getInputStream(), "UTF-8"));
for(String line; (line = br.readLine()) != null; ) {
// process a whole line of text at once. e.g.
System.out.println(line);
}
Это будет декодировать текст, читать целые строки и обрабатывать любые многобайтовые символы.