- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试通过连接服务器 (Java) - 客户端 (Android) 实时制作音频循环。服务器(PC/Java)客户端向客户端(手机/Android)发送数据并返回。
我放一段代码说明一下:- 服务器
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* This class implements a TCP Server.<p>
*/
public class GTCPServer {
public static final int SERVER_PORT = 4444; // Port number
private boolean running = true; // Boolean to control stream
private ServerSocket serverSocket;
// Input-Output streams:
private DataInputStream dis;
private DataOutputStream dos;
// Buffer:
private byte[] bytes;
private static final int BUFFER_SIZE = 512 * 4; // Size
/**
* Constructor. Starts Server.
*/
public GTCPServer() {
bytes = new byte[BUFFER_SIZE]; // Create buffer
// Put values to test:
bytes[0] = 3;
bytes[BUFFER_SIZE - 1] = 7;
try {
// Create Server Socket and wait connections.
serverSocket = new ServerSocket(SERVER_PORT);
System.out.println("Conecting...");
// Within accept methode we are waiting connection.
// When it's ready, create Client Socket:
Socket client = serverSocket.accept();
System.out.println("Receiving...");
try {
// Streams:
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
} catch (Exception e) {
System.out.println("Error.");
e.printStackTrace();
}
} catch (Exception e) {
System.out.println("Error.");
e.printStackTrace();
}
} // GTCPServer()
/**
* Send (write) a byte[] buffer within TCP.
* @param buffer - Data.
* @param offset - Position.
* @param count - Number of bytes to write.
*/
public void write(byte[] buffer, int offset, int count) {
try {
dos.write(buffer, offset, count); // Write
} catch (IOException e) {
e.printStackTrace();
}
} // write()
} // GTCPServer
客户:
import android.util.Log;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import com.appacoustic.java.g.G;
public class GTCPClient_A {
public static final String SERVER_IP = "192.168.1.101"; // Server IP (PC)
public static final int SERVER_PORT = 4444; // Port number
private boolean running = true; // Boolean to control stream
// Input-output streams:
private DataInputStream dis;
private DataOutputStream dos;
// Buffer:
private byte[] bytes;
private static final int BUFFER_SIZE = 512 * 4; // Size
/**
* Constructor.
*/
public GTCPClient_A() {
bytes = new byte[BUFFER_SIZE]; // Create buffer
} // GTCPClient_A()
/**
* Execute Thread. It isn't override because we are using a subclass (connectTask) wich extends AsyncTask.
*/
public void run() {
try {
// Get InetAddress (IPv4 Server)
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
Log.e("GTCPClient_A", "Conecting...");
// Create a Socket ti connect with Server:
Socket socket = new Socket(serverAddr, SERVER_PORT);
try {
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
int lap = 0; // Para llevar la cuenta de las vueltas
while (running) {
dis.read(bytes); // Leemos por TCP
System.out.println("IN_ini_["+lap+"]: "+bytes[0]);
System.out.println("IN_fin_["+lap+"]: "+bytes[BUFFER_SIZE - 1]);
G.toc = System.currentTimeMillis();
G.ticToc();
G.tic = G.toc;
dos.write(bytes); // Escribimos por TCP
System.out.println("OUT_ini_["+lap+"]: "+bytes[0]);
System.out.println("OUT_fin_["+lap+"]: "+bytes[BUFFER_SIZE - 1]);
lap++;
}
} catch (Exception e) {
Log.e("GTCP", "SERVIDOR: Error", e);
} finally {
socket.close();
}
} catch (Exception e) {
Log.e("GTCP", "CLIENTE: Error", e);
}
} // run()
} // GTCPClient_A
我已经通过蓝牙和 TCP 对其进行编程,但效果不佳。延迟太多(大约 5 秒)。令我惊讶的是,当尝试在 Java 而不是 Android 中部署客户端时,确实有效(代码几乎相同)。事实上,我对着麦克风说话(我安排了 JASIOHost ASIO 驱动程序),从我有服务器的计算机,TCP 数据传输到同一 WiFi 内的另一台计算机,返回并听到服务器计算机中实时完美的扬声器。
所以,问题似乎出在 Android 上。但我想要的是使用智能手机或平板电脑作为客户端。
我也在客户端测试过这条线:android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);//优先级
找个磨损尝试不成功的解决方案...
最佳答案
最后的解决方案是 UDP。它比 TCP 或蓝牙更快。我把你的代码放在这里。现在 Server 是 Android:
public class GUDPServer_A {
private int PORT_NUMBER = 4444; // Nº de puerto de conexión. Usamos el mismo para Servidor y Cliente (para no liar)
private DatagramSocket serverSocket; // Socket Servidor
private DatagramPacket inPacket; // Paquete de entrada
private DatagramPacket outPacket; // Paquete de salida
private boolean running = true; // Booleano para indicar que se está a la escucha del Cliente
// Buffers:
public static final int BUFFER_SIZE = 1024 * 4;
public static byte[] bytes_in;
public static byte[] bytes_out;
public GUDPServer_A() {
bytes_in = new byte[BUFFER_SIZE];
bytes_out = new byte[BUFFER_SIZE];
try {
serverSocket = new DatagramSocket(PORT_NUMBER); // Sólo se hace una vez ya que siempre estamos mandando por el mismo puerto
System.out.println("Servidor UDP en marcha.");
} catch (SocketException e) {
System.out.println("Socket: "+e.getMessage());
} catch (IOException e) {
System.out.println("IO: "+e.getMessage());
}
} // GUDPServer_A()
/**
* Ejecución del hilo. El método no está sobreescrito porque usamos una subclase (connectTask) que extiende de AsyncTask.
*/
public void run() {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); // Le damos prioridad "-19" al Thread (Lo máximo es -20)
int lap = 0; // Para llevar la cuenta de las vueltas
while (running) {
read(bytes_in); // Recibimos el paquete desde UDP
// Procesamos (de momento lo dejamos igual, simplemente clonamos):
bytes_out = bytes_in.clone();
G.toc = System.currentTimeMillis();
G.ticToc();
G.tic = G.toc;
write(bytes_out); // Enviamos el paquete de vuelta
Log.d("Vuelta:", ""+lap);
lap++;
}
} // run()
/**
* Envía (escribe) un buffer de bytes por UDP.
* @param buffer - La memoria intermedia donde se almacenan los datos a enviar.
*/
public void write(byte[] buffer) {
outPacket = new DatagramPacket(buffer, inPacket.getLength(), inPacket.getAddress(), inPacket.getPort());
try {
serverSocket.send(outPacket); // Enviamos el paquete
} catch (IOException e) {
e.printStackTrace();
}
} // write()
/**
* Recibe (lee) un buffer de bytes por UDP.
* @param buffer - La memoria intermedia donde se almacenan los datos a recibir.
*/
public void read(byte[] buffer) {
inPacket = new DatagramPacket(buffer, buffer.length);
try {
serverSocket.receive(inPacket); // Recibimos el paquete
} catch (IOException e) {
e.printStackTrace();
}
} // read()
/**
* Cierra la conexión.
*/
public void stop() {
if (serverSocket != null) {
serverSocket.close();
}
} // stop()
} // GUDPServer_A
并且Client是Java:
public class GUDPClient {
private int PORT_NUMBER = 4444; // Nº de puerto de conexión. Usamos el mismo para Servidor y Cliente (para no liar)
private DatagramSocket clientSocket; // Socket Cliente
private DatagramPacket inPacket; // Paquete de entrada
private DatagramPacket outPacket; // Paquete de salida
private InetAddress host; // Dirección IP del Servidor (LG L5)
public static final String IP_LG = "192.168.1.102"; // IP del Servidor (LG L5)
public static final String IP_TABLET = "192.168.1.105"; // IP del Servidor (Tablet)
/**
* Constructor.
*/
public GUDPClient() {
try {
clientSocket = new DatagramSocket(); // No hace falta darle un nº de puerto (se lo damos al paquete)
host = InetAddress.getByName(IP_LG); // Obtenemos el host del Servidor (LG L5)
//host = InetAddress.getByName(IP_TABLET); // Obtenemos el host del Servidor (Tablet)
System.out.println("Cliente UDP conectado.");
} catch (SocketException e) {
System.out.println("Socket: "+e.getMessage());
} catch (IOException e) {
System.out.println("IO: "+e.getMessage());
}
} // GUDPClient()
/**
* Envía (escribe) un buffer de bytes por UDP.
* @param buffer - La memoria intermedia donde se almacenan los datos a enviar.
*/
public void write(byte[] buffer) {
outPacket = new DatagramPacket(buffer, buffer.length, host, PORT_NUMBER);
try {
clientSocket.send(outPacket); // Enviamos el paquete por UDP
} catch (IOException e) {
e.printStackTrace();
}
} // write()
/**
* Recibe (lee) un buffer de bytes por UDP.
* @param buffer - La memoria intermedia donde se almacenan los datos a recibir.
*/
public void read(byte[] buffer) {
inPacket = new DatagramPacket(buffer, buffer.length);
try {
clientSocket.receive(inPacket); // Recibimos el paquete procesado desde UDP
} catch (IOException e) {
e.printStackTrace();
}
} // read()
/**
* Cierra la conexión.
*/
public void stop() {
if (clientSocket != null) {
clientSocket.close();
}
} // stop()
} // GUDPClient
一件重要的事情是设置快速线程。
安卓:android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
Java: thread.setPriority(Thread.MAX_PRIORITY);
关于java - 实时java android流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19501438/
我最近在/ drawable中添加了一些.gifs,以便可以将它们与按钮一起使用。这个工作正常(没有错误)。现在,当我重建/运行我的应用程序时,出现以下错误: Error: Gradle: Execu
Android 中有返回内部存储数据路径的方法吗? 我有 2 部 Android 智能手机(Samsung s2 和 s7 edge),我在其中安装了一个应用程序。我想使用位于这条路径中的 sqlit
这个问题在这里已经有了答案: What's the difference between "?android:" and "@android:" in an android layout xml f
我只想知道 android 开发手机、android 普通手机和 android root 手机之间的实际区别。 我们不能从实体店或除 android marketplace 以外的其他地方购买开发手
自Gradle更新以来,我正在努力使这个项目达到标准。这是一个团队项目,它使用的是android-apt插件。我已经进行了必要的语法更改(编译->实现和apt->注释处理器),但是编译器仍在告诉我存在
我是android和kotlin的新手,所以请原谅要解决的一个非常简单的问题! 我已经使用导航体系结构组件创建了一个基本应用程序,使用了底部的导航栏和三个导航选项。每个导航选项都指向一个专用片段,该片
我目前正在使用 Facebook official SDK for Android . 我现在正在使用高级示例应用程序,但我不知道如何让它获取应用程序墙/流/状态而不是登录的用户。 这可能吗?在那种情
我在下载文件时遇到问题, 我可以在模拟器中下载文件,但无法在手机上使用。我已经定义了上网和写入 SD 卡的权限。 我在服务器上有一个 doc 文件,如果用户单击下载。它下载文件。这在模拟器中工作正常但
这个问题在这里已经有了答案: What is the difference between gravity and layout_gravity in Android? (22 个答案) 关闭 9
任何人都可以告诉我什么是 android 缓存和应用程序缓存,因为当我们谈论缓存清理应用程序时,它的作用是,缓存清理概念是清理应用程序缓存还是像内存管理一样主存储、RAM、缓存是不同的并且据我所知,缓
假设应用程序 Foo 和 Eggs 在同一台 Android 设备上。任一应用程序都可以获取设备上所有应用程序的列表。一个应用程序是否有可能知道另一个应用程序是否已经运行以及运行了多长时间? 最佳答案
我有点困惑,我只看到了从 android 到 pc 或者从 android 到 pc 的例子。我需要制作一个从两部手机 (android) 连接的 android 应用程序进行视频聊天。我在想,我知道
用于使用 Android 以编程方式锁定屏幕。我从 Stackoverflow 之前关于此的问题中得到了一些好主意,并且我做得很好,但是当我运行该代码时,没有异常和错误。而且,屏幕没有锁定。请在这段代
文档说: android:layout_alignParentStart If true, makes the start edge of this view match the start edge
我不知道这两个属性和高度之间的区别。 以一个TextView为例,如果我将它的layout_width设置为wrap_content,并将它的width设置为50 dip,会发生什么情况? 最佳答案
这两个属性有什么关系?如果我有 android:noHistory="true",那么有 android:finishOnTaskLaunch="true" 有什么意义吗? 最佳答案 假设您的应用中有
我是新手,正在尝试理解以下 XML 代码: 查看 developer.android.com 上的文档,它说“starStyle”是 R.attr 中的常量, public static final
在下面的代码中,为什么当我设置时单选按钮的外观会发生变化 android:layout_width="fill_parent" 和 android:width="fill_parent" 我说的是
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
假设我有一个函数 fun myFunction(name:String, email:String){},当我调用这个函数时 myFunction('Ali', 'ali@test.com ') 如何
我是一名优秀的程序员,十分优秀!