Java Android Client с ПК -сервером подключение замедляется через 5 минут, а затем отключается [закрыто]JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Java Android Client с ПК -сервером подключение замедляется через 5 минут, а затем отключается [закрыто]

Сообщение Anonymous »

Сервер ПК: < /p>

Код: Выделить всё

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {
private static final int PORT = 12345;
private static final List clientConnections = new ArrayList();
private static final ExecutorService executor = Executors.newFixedThreadPool(10);

public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
System.out.println("Server is listening on port " + PORT);
while (true) {
Socket socket = serverSocket.accept();
ClientConnection connection = new ClientConnection(socket);
synchronized (clientConnections) {
clientConnections.add(connection);
}
System.out.println("New client connected: " + socket);
executor.submit(new ClientHandler(connection));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}

public static void broadcast(ArrayList message) {
synchronized (clientConnections) {
Iterator iterator = clientConnections.iterator();
while (iterator.hasNext()) {
ClientConnection connection = iterator.next();
try {
connection.getOutputStream().writeObject(message);
connection.getOutputStream().flush();
} catch (IOException e) {
System.err.println("Hata: Client ile bağlantı kayboldu: " + connection.getSocket());
try {
connection.getSocket().close();
} catch (IOException ex) {
ex.printStackTrace();
}
iterator.remove();
System.out.println("Client bağlantısı kaldırıldı: " + connection.getSocket());
}
}
}
}

public static void removeConnection(ClientConnection connection) {
synchronized (clientConnections) {
clientConnections.remove(connection);
System.out.println("Connection listeden çıkarıldı: " + connection.getSocket());
}
}
}

class ClientHandler implements Runnable {
private final ClientConnection connection;

public ClientHandler(ClientConnection connection) {
this.connection = connection;
}

@Override
public void run() {
try (ObjectInputStream in = connection.getInputStream()) {
while (!Thread.currentThread().isInterrupted() && !connection.getSocket().isClosed()) {
Object obj = in.readObject();
if (!(obj instanceof ArrayList)) {
System.out.println("Beklenmeyen veri tipi: " + obj.getClass().getName());
continue;
}
@SuppressWarnings("unchecked")
ArrayList receivedList = (ArrayList) obj;
if (receivedList.size() < 3) {
System.out.println("Yetersiz veri alındı, geçildi.");
continue;
}
Object passwordObj = receivedList.get(1);
Object codeObj = receivedList.get(2);
String password = (passwordObj instanceof String) ? (String) passwordObj : "Bilinmiyor";
int code = (codeObj instanceof Integer) ? (Integer) codeObj : -1;
System.out.println("Client'tan gelen veri:");
System.out.println("Şifre: " + password);
System.out.println("Kod: " + code);
Main.broadcast(receivedList);
}
} catch (IOException e) {
System.out.println("Client bağlantısı kapandı veya hata: " + e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println("ClassNotFoundException: "  + e.getMessage());
e.printStackTrace();
} finally {
try {
connection.getSocket().close();
} catch (IOException e) {
e.printStackTrace();
}
Main.removeConnection(connection);
System.out.println("Client bağlantısı sonlandırıldı: "  + connection.getSocket());
}
}
}

class ClientConnection {
private final Socket socket;
private final ObjectOutputStream out;
private final ObjectInputStream in;

public ClientConnection(Socket socket) throws IOException {
this.socket = socket;
this.out = new ObjectOutputStream(socket.getOutputStream());
this.in = new ObjectInputStream(socket.getInputStream());
}

public Socket getSocket() {
return socket;
}

public ObjectOutputStream getOutputStream() {
return out;
}

public ObjectInputStream getInputStream() {
return in;
}
}
< /code>
android java client: < /p>
package com.example.mydneme2;

import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.SurfaceTexture;
import android.media.MediaCodec;
import android.media.MediaCodec.BufferInfo;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
import android.view.TextureView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.google.common.util.concurrent.ListenableFuture;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class goruntulu_konusma_gonder extends AppCompatActivity {

private static final String TAG = "GoruntuluKonusma";

private TextureView textureView1, textureView2;
private TextView bitrateTextView;

private MediaCodec encoder;
private Surface encoderInputSurface;
private MediaCodec decoder;
private Surface decoderOutputSurface;
private boolean decoderStarted = false;

private boolean isEncoding = false;
private final Handler handler = new Handler(Looper.getMainLooper());
private ExecutorService executor = Executors.newSingleThreadExecutor();

private socketClient socketClient;

private final int WIDTH = 1280;
private final int HEIGHT = 720;
private final int BITRATE = 800_000;
private final int FPS = 15;

private Preview preview, encoderPreview;
private long sentBytesTotal = 0;
private long receivedBytesTotal = 0;
private Runnable bitrateRunnable;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_goruntulu_konusma_gonder);

textureView1 = findViewById(R.id.textureView1);
textureView2 = findViewById(R.id.textureView2);
bitrateTextView = findViewById(R.id.trafficInfoTextView);

if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1001);
} else {
setupEncoderDecoderAndCamera();
}

startBitrateMonitor();
}

private void startBitrateMonitor() {
bitrateRunnable = new Runnable() {
private long lastSent = 0;
private long lastReceived = 0;
@Override
public void run() {
long sentNow = sentBytesTotal;
long recvNow = receivedBytesTotal;
long sentKbps = ((sentNow - lastSent) * 8) / 1000;
long recvKbps = ((recvNow - lastReceived) * 8) / 1000;

lastSent = sentNow;
lastReceived = recvNow;

bitrateTextView.setText("Gönderilen: " + sentKbps + " kbps\nAlınan: " + recvKbps + "  kbps");

handler.postDelayed(this, 1000);
}
};
handler.postDelayed(bitrateRunnable, 1000);
}

@Override
protected void onDestroy() {
isEncoding = false;
handler.removeCallbacks(bitrateRunnable);

if (executor != null && !executor.isShutdown()) executor.shutdownNow();
if (encoder != null) {
try { encoder.stop(); } catch (Exception ignored) {}
try { encoder.release(); } catch (Exception ignored) {}
}
if (decoder != null && decoderStarted) {
try { decoder.stop(); } catch (Exception ignored) {}
try { decoder.release(); } catch (Exception ignored) {}
}
if (decoderOutputSurface != null) decoderOutputSurface.release();
if (socketClient != null) socketClient.close();
super.onDestroy();
}

private void setupEncoderDecoderAndCamera() {
try {
setupEncoder();
setupDecoder();
socketClient = new socketClient();

if (textureView1.isAvailable()) {
startCameraX();
} else {
textureView1.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) { startCameraX(); }
@Override public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {}
@Override public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) { return true; }
@Override public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {}
});
}
} catch (IOException e) {
Log.e(TAG, "Encoder/Decoder setup hatası", e);
}
}

private void setupEncoder() throws IOException {
encoder = MediaCodec.createEncoderByType("video/avc");
MediaFormat format = MediaFormat.createVideoFormat("video/avc", WIDTH, HEIGHT);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
format.setInteger(MediaFormat.KEY_BIT_RATE, BITRATE);
format.setInteger(MediaFormat.KEY_FRAME_RATE, FPS);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);

encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
encoderInputSurface = encoder.createInputSurface();
encoder.start();
isEncoding = true;

startEncodingLoop();
}

private void setupDecoder() throws IOException {
decoder = MediaCodec.createDecoderByType("video/avc");
MediaFormat format = MediaFormat.createVideoFormat("video/avc", WIDTH, HEIGHT);

textureView2.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int width, int height) {
try {
if (decoderOutputSurface != null) decoderOutputSurface.release();
decoderOutputSurface = new Surface(surfaceTexture);
decoder.configure(format, decoderOutputSurface, null, 0);
decoder.start();
decoderStarted = true;
} catch (Exception e) {
Log.e(TAG, "Decoder konfigurasyon hatası", e);
decoderStarted = false;
}
}
@Override public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surfaceTexture, int width, int height) {}
@Override public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surfaceTexture) {
if (decoderOutputSurface != null) decoderOutputSurface.release();
if (decoder != null && decoderStarted) {
try { decoder.stop(); } catch (Exception ignored) {}
try { decoder.release(); } catch (Exception ignored) {}
decoderStarted = false;
}
return true;
}
@Override public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surfaceTexture) {}
});
}

private void startCameraX() {
ListenableFuture
  cameraProviderFuture = ProcessCameraProvider.getInstance(this);
cameraProviderFuture.addListener(() -> {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
cameraProvider.unbindAll();

preview = new Preview.Builder().setTargetResolution(new Size(WIDTH, HEIGHT)).build();
preview.setSurfaceProvider(request -> {
SurfaceTexture texture = textureView1.getSurfaceTexture();
if (texture != null) {
texture.setDefaultBufferSize(WIDTH, HEIGHT);
Surface previewSurface = new Surface(texture);
request.provideSurface(previewSurface, ContextCompat.getMainExecutor(this), result -> previewSurface.release());
} else {
request.willNotProvideSurface();
}
});

encoderPreview = new Preview.Builder().setTargetResolution(new Size(WIDTH, HEIGHT)).build();
encoderPreview.setSurfaceProvider(request -> request.provideSurface(encoderInputSurface, ContextCompat.getMainExecutor(this), result -> {}));

cameraProvider.bindToLifecycle(this, CameraSelector.DEFAULT_BACK_CAMERA, preview, encoderPreview);

} catch (Exception e) {
Log.e(TAG, "CameraX başlatılamadı", e);
}
}, ContextCompat.getMainExecutor(this));
}

private void startEncodingLoop() {
executor.execute(() -> {
BufferInfo bufferInfo = new BufferInfo();
while (isEncoding) {
try {
int outputIndex = encoder.dequeueOutputBuffer(bufferInfo, 10000);
if (outputIndex >= 0) {
ByteBuffer encodedBuffer = encoder.getOutputBuffer(outputIndex);
if (encodedBuffer != null && bufferInfo.size > 0) {
byte[] h264Data = new byte[bufferInfo.size];
encodedBuffer.position(bufferInfo.offset);
encodedBuffer.limit(bufferInfo.offset + bufferInfo.size);
encodedBuffer.get(h264Data);

ArrayList dataToSend = new ArrayList();
dataToSend.add(h264Data);
dataToSend.add("tag1");
dataToSend.add(42);
dataToSend.add(System.currentTimeMillis() / 1000L);

socketClient.sendData(dataToSend);
}
encoder.releaseOutputBuffer(outputIndex, false);
}
} catch (Exception e) {
Log.e(TAG, "Encode hatası", e);
}
}
});
}

private int getByteSize(ArrayList list) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(list);
oos.close();
return baos.toByteArray().length;
} catch (IOException e) {
return 0;
}
}

private class socketClient {
private final String SERVER_IP = "192.168.1.100";
private final int SERVER_PORT = 12345;
private Socket socket;
private ObjectOutputStream objectOutputStream;
private ObjectInputStream objectInputStream;
private ExecutorService executorService = Executors.newSingleThreadExecutor();
private volatile boolean isConnected = false;

public socketClient() {
connectToServer();
}

private void connectToServer() {
executorService.execute(() ->  {
try {
socket = new Socket(SERVER_IP, SERVER_PORT);
objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectInputStream = new ObjectInputStream(socket.getInputStream());
isConnected = true;
listenForData();
Log.i(TAG, "Server'a bağlandı");
} catch (IOException e) {
isConnected = false;
Log.e(TAG, "Server bağlantısı başarısız", e);
}
});
}

public void sendData(final ArrayList data) {
executorService.execute(() -> {
try {
if (isConnected && objectOutputStream != null) {
synchronized (objectOutputStream) {
objectOutputStream.writeObject(data);
byte[] byteArray = (byte[]) data.get(0);
sentBytesTotal += byteArray.length;
objectOutputStream.flush();
}
}
} catch (IOException e) {
isConnected = false;
Log.e(TAG, "Veri gönderilemedi", e);
}
});
}

private void listenForData() {
new Thread(() -> {
try {
while (isConnected && !socket.isClosed()) {
Object received = objectInputStream.readObject();
if (received instanceof ArrayList) {
ArrayList list = (ArrayList) received;
receivedBytesTotal += getByteSize(list);
handler.post(() -> handleReceivedData(list));
}
}
} catch (Exception e) {
isConnected = false;
Log.e(TAG, "Veri dinleme hatası", e);
}
}).start();
}

public void close() {
isConnected = false;
try { if (objectInputStream != null) objectInputStream.close(); } catch (IOException ignored) {}
try { if (objectOutputStream != null) objectOutputStream.close(); } catch (IOException ignored) {}
try { if (socket != null && !socket.isClosed()) socket.close(); } catch (IOException ignored) {}
executorService.shutdownNow();
}
}

private void handleReceivedData(ArrayList receivedData) {
try {
if (receivedData.size() < 1) return;
byte[] h264Data = (byte[]) receivedData.get(0);

if (decoder == null || !decoderStarted) return;

int inputBufferIndex = decoder.dequeueInputBuffer(10000);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = decoder.getInputBuffer(inputBufferIndex);
if (inputBuffer != null) {
inputBuffer.clear();
inputBuffer.put(h264Data);
decoder.queueInputBuffer(inputBufferIndex, 0, h264Data.length, System.nanoTime() / 1000, 0);
}
}

BufferInfo info = new BufferInfo();
int outputIndex = decoder.dequeueOutputBuffer(info, 10000);
while (outputIndex >= 0) {
decoder.releaseOutputBuffer(outputIndex, true);
outputIndex = decoder.dequeueOutputBuffer(info, 0);
}
} catch (Exception e) {
Log.e(TAG, "Veri işlenirken hata", e);
}
}
}
< /code>
У меня есть клиент Java Android, который подключается к серверу Java, работающему на ПК через сокет. Первоначально соединение работает нормально, а передача данных начинается плавно. Однако примерно через 5 минут связь с сокетами значительно снижается, и в конечном итоге подключение падает, что приводит к неожиданному закрытию приложения.
Вот краткое описание моей настройки: 

 Android Client использует сокет 
для непрерывного отправки данных. Входящие байты. Тем не менее, производительность снижается с течением времени. < /P>
Я подозреваю, что может быть какая -то утечка ресурса или насыщение буфера буфера, но я не уверен. Практики для продолжительных подключений разъемов между приложениями Android и PC Java?>

Подробнее здесь: https://stackoverflow.com/questions/797 ... minutes-an
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»