Ошибка с чтением входного потока сокета в Java 1.8
При использовании следующего кода возникает ошибка при чтении входного потока. Я использую следующий код:
public void run() {
try {
SocketAddress sockaddr = new InetSocketAddress(nServer, nPort);
nsocket = new Socket();
nsocket.connect(sockaddr, 10 * 1000);
if (nsocket.isConnected()) {
nsocket.setSoTimeout(20 * 1000);
nis = nsocket.getInputStream();
nos = nsocket.getOutputStream();
if (nProtocol.equals("ntripv1")) {
String requestmsg = "GET /" + nMountpoint + " HTTP/1.0\r\n";
requestmsg += "User-Agent: NTRIP LefebureNTRIPClient/20131124\r\n";
requestmsg += "Accept: */*\r\n" + "Connection: close\r\n";
if (nUsername.length() > 0) {
requestmsg += "Authorization: Basic " + ToBase64(nUsername + ":" + nPassword) +"\r\n";
}
requestmsg += "\r\n";
nos.write(requestmsg.getBytes());
} else {
}
byte[] buffer = new byte[4096];
int read = nis.read(buffer, 0, 4096);
while (read != -1) {
byte[] tempdata = new byte[read];
System.arraycopy(buffer, 0, tempdata, 0, read);
try {
dataMessenger.send(Message.obtain(null, MSG_NETWORK_GOT_DATA, tempdata));
} catch (RemoteException e2) {
}
read = nis.read(buffer, 0, 4096);
}
}
} catch (SocketTimeoutException ex) {
try {
dataMessenger.send(Message.obtain(null, MSG_NETWORK_TIMEOUT));
} catch (RemoteException e2) {
}
} catch (Exception e) {
LogMessage(e.getLocalizedMessage());
e.printStackTrace();
} finally {
try {
nis.close();
nos.close();
nsocket.close();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
try {
dataMessenger.send(Message.obtain(null, MSG_NETWORK_FINISHED));
} catch (RemoteException e2) {
}
}
}
Серверная часть хорошо работает с другими приложениями. Этот код также устанавливает соединение с сервером и получает некоторую дату, но через некоторое время завершает работу на nis.read.
Коды написаны с Java 1.8 для Android Studio.
У кого-нибудь есть идея получить всю информацию с сервера и прочитать всю информацию, чтобы ее можно было использовать в приложении.
Обновление Ошибка выдается следующей строкой в цикле while:
read = nis.read(buffer, 0, 4096);
Обновление 2 Данная ошибка: System.err: java.net.SocketException: сброс подключения
1 ответ
Всегда.flush() в выходном потоке, когда вы закончите отправку сообщения. Думайте об этом как о коммите, если нужно, но на самом деле это просто вопрос буферизации.
Во-вторых. очень возможно, что сервер использует http keep-alive и не зависает (даже если вы Connection: close
, который также используется по умолчанию для HTTP/1.0); тогда работа на стороне клиента - повесить трубку. Для этого вам нужно обнаружить, что контент закончен, поэтому вы должны поддерживать как заголовок ответа с длиной содержимого, если он есть, так и "chunked" транспортную кодировку (вероятно, если ответ больше, чем произвольная величина, например, несколько КБ). HTTP хороший спорт...!
Вы также можете попробовать версию http без строки в строке GET (подразумевается HTTP 0.9), которая, я думаю, просто не поддерживает поддержку активности http.
Если сервер предполагает, что keep-alive включен (см. https://en.wikipedia.org/wiki/HTTP_persistent_connection), это объясняет поведение. Смотрите также https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection
Я рекомендую вам установить Wireshark и понюхать трафик. Это относительно интуитивно понятно. Вы увидите, были ли отправлены все данные и действительно ли сервер забыл закрыть (TCP FIN).