Я в основном пытаюсь разместить сервер на устройстве Android. Клиентские устройства подключаются к серверу через TCP и отправляют запросы. Сервер выполняет действие, запрошенное клиентом, а затем записывает данные обратно в сокет. Соединение не прерывается сервером, и запросы должны непрерывно считываться через сокет и отвечать.
Примечание. Первые 4 байта каждого сообщения запроса содержат длину фактического сообщения/запроса.
Функция parseXmlInputAndExecuteCmd выполняет различные асинхронные операции в зависимости от содержимого входной XML-строки. Это в конечном итоге приводит к изменению логического значения переменной allowResponse в true и генерируется определенный ответ, который сохраняется в переменной типа String, называемой "response". Когда логический "allowResponse" становится истинным, поток возобновляет выполнение и записывает ответ обратно в сокет OutputStream
Некоторые из этих асинхронных операций включают подключение и отключение от корпоративного VPN. Это может быть причиной ошибки?
Используются некоторые переменные уровня класса:
private volatile boolean allowResponse = false;
private String response;
Код сервера:
private void startServer() {
try {
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
Socket connectionSocket = serverSocket.accept();
BufferedInputStream bufInpStream = new BufferedInputStream(connectionSocket.getInputStream());
BufferedOutputStream bufOutStream = new BufferedOutputStream(connectionSocket.getOutputStream());
ByteArrayOutputStream contentLengthBaos = new ByteArrayOutputStream();
int c;
int count = 0;
while ((c = bufInpStream.read()) != -1) {
contentLengthBaos.write(c);
count++;
if (count == 4) {
int contLen = getMessageLength(contentLengthBaos);
String content = getMessageContent(bufInpStream, contLen);
parseXmlInputAndExecuteCmd(content);
count = 0;
while (!allowResponse) {
Thread.sleep(1000);
}
allowResponse = false;
byte[] responseDataBytes = response.getBytes();
int outputContLen = responseDataBytes.length;
byte[] contLengthBytes = ByteBuffer.allocate(4).putInt(outputContLen).array();
ByteArrayOutputStream o = new ByteArrayOutputStream();
o.write(contLengthBytes);
o.write(responseDataBytes);
byte finalOutPutBytes[] = o.toByteArray();
bufOutStream.write(finalOutPutBytes);
bufOutStream.flush();
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@NonNull
private String getMessageContent(BufferedInputStream inFromClient, int contLen) throws IOException {
ByteArrayOutputStream contentBaos = new ByteArrayOutputStream();
byte[] contentBytes = new byte[contLen];
for (int i = 0; i < contLen; i++) {
contentBaos.write(inFromClient.read());
ByteArrayInputStream bais = new ByteArrayInputStream(contentBaos.toByteArray());
bais.read(contentBytes);
}
String content = new String(contentBytes);
Log.d(TAG, "Content : " + content);
return content;
}
private int getMessageLength(ByteArrayOutputStream contentLengthBaos) {
byte[] firstFourBytesArr = contentLengthBaos.toByteArray();
int contLen = new BigInteger(firstFourBytesArr).intValue();
contentLengthBaos = new ByteArrayOutputStream();
Log.d(TAG, "Content length: " + contLen);
return contLen;
}
Сервер запускается с использованием следующих строк кода:
Thread serverThread = new Thread(new Runnable() {
@Override
public void run() {
startServer();
}
});
serverThread.start();
Я получаю следующую трассировку стека ошибок:
W/System.err: java.net.SocketException: Software caused connection abort
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:114)
W/System.err: at java.net.SocketInputStream.read(SocketInputStream.java:170)
W/System.err: at java.net.SocketInputStream.read(SocketInputStream.java:139)
W/System.err: at java.io.BufferedInputStream.fill(BufferedInputStream.java:248)
W/System.err: at java.io.BufferedInputStream.read(BufferedInputStream.java:267)
at com.example.umathur.myapplication.MainActivity.startServer(MainActivity.java:192)
at com.example.umathur.myapplication.MainActivity.access$000(MainActivity.java:61)
at com.example.umathur.myapplication.MainActivity$1.run(MainActivity.java:139)
at java.lang.Thread.run(Thread.java:764)
Я получаю сообщение об ошибке: java.net.SocketException: Software caused connection abort
Я не уверен, где я ошибаюсь в использовании потока ввода/вывода. Im получает ошибку в следующей строке (номер строки 192, как указано в stacktrace):
while ((c = inputStream.read()) != -1)
В некоторых похожих вопросах о StackOverflow я видел людей, заявляющих, что это может быть проблема конфигурации корпоративного брандмауэра? Это верно? Если да, то как это сделать?
Это может быть проблема с кодом клиента (к которому у меня нет доступа), который не написан правильно?