gpt4 book ai didi

当字节值为正时,Java UDP 服务器未接收数据包。在本地主机上工作正常,但在外部 IP 服务器上工作不正常

转载 作者:行者123 更新时间:2023-12-01 10:23:07 25 4
gpt4 key购买 nike

服务器代码

class UDPServer {
public static void main(String args[]) throws Exception
{
DatagramSocket serverSocket = new DatagramSocket(9876);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while(true) {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
System.out.println("RECEIVED: ");
sendData = receivePacket.getData();

InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();

DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
}
}

和客户

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.util.Log;

public class AudioCall {

private static final String LOG_TAG = "AudioCall";
private static final int SAMPLE_RATE = 8000; // Hertz
private static final int SAMPLE_INTERVAL = 20; // Milliseconds
private static final int SAMPLE_SIZE = 2; // Bytes
private static final int BUF_SIZE = SAMPLE_INTERVAL * SAMPLE_INTERVAL * SAMPLE_SIZE * 2; //Bytes
private InetAddress address; // Address to call
private int port = 9876; // Port the packets are addressed to
private boolean mic = false; // Enable mic?
private boolean speakers = false; // Enable speakers?

public AudioCall(InetAddress address) {

this.address = address;
}

public void startCall() {

startMic();
startSpeakers();
}

public void endCall() {

Log.i(LOG_TAG, "Ending call!");
muteMic();
muteSpeakers();
}

public void muteMic() {

mic = false;
}

public void muteSpeakers() {

speakers = false;
}

public void startMic() {
// Creates the thread for capturing and transmitting audio
mic = true;
Thread thread = new Thread(new Runnable() {

@Override
public void run() {
// Create an instance of the AudioRecord class
Log.i(LOG_TAG, "Send thread started. Thread id: " + Thread.currentThread().getId());
int a = AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT)*10;
System.out.println("test: " + a);
AudioRecord audioRecorder = new AudioRecord (MediaRecorder.AudioSource.MIC, SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT)*10);
int bytes_read = 0;
int bytes_sent = 0;
//byte[] buf = new byte[BUF_SIZE]; // 1600
//byte buf[BUF_SIZE] = new byte[BUF_SIZE];
try {
// Create a socket and start recording
Log.i(LOG_TAG, "Packet destination: " + address.toString());
DatagramSocket socket = new DatagramSocket();
audioRecorder.startRecording();
System.out.println("We can send now: " + mic);
DatagramSocket clientSocket = new DatagramSocket();
while(mic) {

// #############


InetAddress IPAddress = InetAddress.getByName("212.109.192.201");
byte[] sendData = new byte[1024];
bytes_read = audioRecorder.read(sendData, 0, 1024);
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
clientSocket.send(sendPacket);
// ##############



// Capture audio from the mic and transmit it
//bytes_read = audioRecorder.read(buf, 0, BUF_SIZE);
//audioRecorder.read(buf, 0, BUF_SIZE);

// byte[] buf = new byte[BUF_SIZE];
// DatagramPacket packet = new DatagramPacket(buf, 1024, IPAddress, 9876);
//DatagramPacket packet = new DatagramPacket(buf, bytes_read, address, port);
// socket.send(packet);
bytes_sent += bytes_read;
Log.i(LOG_TAG, "Total bytes sent: " + bytes_sent);
// Thread.sleep(SAMPLE_INTERVAL, 0);
}
// Stop recording and release resources
audioRecorder.stop();
audioRecorder.release();
socket.disconnect();
socket.close();
mic = false;
return;
}
// catch(InterruptedException e) {
//
// Log.e(LOG_TAG, "InterruptedException: " + e.toString());
// mic = false;
// }
catch(SocketException e) {

Log.e(LOG_TAG, "SocketException: " + e.toString());
mic = false;
}
catch(UnknownHostException e) {

Log.e(LOG_TAG, "UnknownHostException: " + e.toString());
mic = false;
}
catch(IOException e) {

Log.e(LOG_TAG, "IOException: " + e.toString());
mic = false;
}
}
});
thread.start();
}

public void startSpeakers() {
// Creates the thread for receiving and playing back audio
if(!speakers) {

speakers = true;
Thread receiveThread = new Thread(new Runnable() {

@Override
public void run() {
// Create an instance of AudioTrack, used for playing back audio
Log.i(LOG_TAG, "Receive thread started. Thread id: " + Thread.currentThread().getId());
AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, BUF_SIZE, AudioTrack.MODE_STREAM);
track.play();
try {
// Define a socket to receive the audio
DatagramSocket socket = new DatagramSocket(port);
byte[] buf = new byte[BUF_SIZE];
System.out.println("We can listen now: " + speakers);
while(speakers) {
// Play back the audio received from packets
DatagramPacket packet = new DatagramPacket(buf, BUF_SIZE);
socket.receive(packet);
Log.i(LOG_TAG, "Packet received: " + packet.getLength());
track.write(packet.getData(), 0, BUF_SIZE);
}
// Stop playing back and release resources
socket.disconnect();
socket.close();
track.stop();
track.flush();
track.release();
speakers = false;
return;
}
catch(SocketException e) {

Log.e(LOG_TAG, "SocketException: " + e.toString());
speakers = false;
}
catch(IOException e) {

Log.e(LOG_TAG, "IOException: " + e.toString());
speakers = false;
}
}
});
receiveThread.start();
}
}
}

在本地主机上一切正常,但 UDP 服务器在公共(public)服务器上不接收,并且在某些情况下它只接收前 4 个数据包然后停止。服务器操作系统是ubuntu 14.0版本,无防火墙。我注意到,当UDP数据包的字节值为负值时,它会接收UDP数据包,但当字节值为正值时,它不会接收UDP数据包。 Android list 一切都很好,它具有互联网和其他所需的权限。我想创建一个应用程序,它像一个 channel 一样创建,并将音频广播到该 channel 。任何客户端都可以通过收听特定 channel 来收听音频。问题是它应该是实时的并且具有搜索功能,因此当您实时收听时,可以返回之前收听几秒钟,甚至从头开始收听。请问有什么建议吗?我将非常感谢您的回复

最佳答案

正如评论中所述,您描述的情况是不可能的。然而这个:

while(true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
System.out.println("RECEIVED: ");
sendData = receivePacket.getData();

InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}

不正确。无论实际收到什么,您总是以 1024 字节进行回复。由于接收到的数据包已经包含了自己的长度和源地址,因此可以大大简化为:

while(true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
System.out.println("RECEIVED: ");
serverSocket.send(receivePacket);
}

在客户端中,您不需要在循环内不断获取相同的 InetAddress 以及以下内容:

bytes_read =  audioRecorder.read(sendData, 0, 1024);
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876);

应该是:

bytes_read =  audioRecorder.read(sendData, 0, 1024);
if (bytesRead == -1)
break;
DatagramPacket sendPacket = new DatagramPacket(sendData, bytesRead, IPAddress, 9876);

关于当字节值为正时,Java UDP 服务器未接收数据包。在本地主机上工作正常,但在外部 IP 服务器上工作不正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35465125/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com