Сервер ПК: < /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>
hi, < /p>
У меня есть клиент Java Android, который подключается к серверу Java, работающему на ПК через сокет. Однако примерно через 5 минут связь с сокетом значительно замедляется, и в конечном итоге подключение падает, что приводит к неожиданному закрытию приложения. Байты. Тем не менее, производительность снижается с течением времени. < /P>
Я подозреваю, что может быть какая -то утечка ресурса или насыщение буфера буфера, но я не уверен. практика для продолжительных соединений сокетов между приложениями Android и PC Java?>
Подробнее здесь: https://stackoverflow.com/questions/797 ... minutes-an
Java Android Client с ПК -сервером подключение замедляется через 5 минут, а затем отключается [закрыто] ⇐ JAVA
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение