gpt4 book ai didi

java - 为什么我可以接收广播,但无法与应用程序中的特定套接字通信?

转载 作者:行者123 更新时间:2023-12-02 10:50:26 25 4
gpt4 key购买 nike

首先是一些有关我的设置的信息。我有一部 S8 手机,我在其中运行这个基于 Google 的 AR-Devkit 演示的应用程序。

  public void closeSocket(DatagramSocket socket) {

if (socket != null && socket.isConnected() ) {
while (!socket.isConnected()) {
socket.disconnect();
try {
Thread.sleep(SpringAR.TIME_OUT_IN_BROADCAST);
} catch (InterruptedException e) {
Log.d(SpringAR.protocollDebugLogPrefix, " Socket Closing interrupted");
e.printStackTrace();
}
}
}

if (socket != null && !socket.isClosed()) {
socket.close();
while (!socket.isClosed()) {
try {
Thread.sleep(SpringAR.TIME_OUT_IN_BROADCAST);
} catch (InterruptedException e) {
Log.d(SpringAR.protocollDebugLogPrefix, " Socket Closing interrupted");
e.printStackTrace();
}
}
}
}

public DatagramSocket createSocket(InetAddress ipAddress, int port) {
try {
DatagramSocket socket = new DatagramSocket(null);
InetSocketAddress address = new InetSocketAddress(ipAddress, port);
socket.setReuseAddress(true);
socket.bind(address);

return socket;

} catch (IOException e) {
e.printStackTrace();
}
return null;
}

public DatagramSocket getBroadcastListenerSocket() throws IOException {

InetSocketAddress anyAdress = new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 9000);
DatagramSocket socket = new DatagramSocket(null);
socket.setSoTimeout(30);
socket.setReuseAddress(true);
socket.bind(anyAdress);
return socket;
}

public DatagramSocket getBroadcastSenderSocket(DatagramSocket oldSocket) {

DatagramSocket socket = null;
try {
ARDeviceAddress = InetAddress.getByName(comonUtils.getIPAddress(true));
socket = getSocket(oldSocket, ARDeviceAddress, SpringAR.UDP_SERVER_PORT, null);
socket.setBroadcast(true);
socket.setSoTimeout(SpringAR.TIME_OF_FRAME_IN_MS);
} catch (IOException e) {
e.printStackTrace();
}

return socket;
}

public DatagramSocket getSocket(DatagramSocket oldSocket, InetAddress ipAddress, int port, InetAddress targetAddress) {

if (oldSocket != null ) {
closeSocket(oldSocket);
}
DatagramSocket socket = null;
try {
socket = createSocket(ipAddress, port);
socket.setBroadcast(false);
socket.setSoTimeout(SpringAR.TIME_OF_FRAME_IN_MS);
if (targetAddress != null)
socket.connect(targetAddress, port);

} catch (SocketException e) {
e.printStackTrace();
}
return socket;
}

public class DatagramReciever extends Thread {

private String datagramToSend = "";
private boolean newDatagramToSend = false;
private DatagramPacket snd_packet;

DatagramSocket senderSocket = null;
DatagramSocket listenerSocket = null;
private DatagramSocket broadCastListenerSocket;

//Buffer gettters and setters
private int writeBuffer = 0;
private SpringAR.comStates oldState;

int getReadBuffer() {
if (writeBuffer == 1) return 0;
return 1;
}

void switchBuffer() {
recieveByteIndex = 0;
writeBuffer = getReadBuffer();
}

public String dbg_message = "";
//Management Communication Headers

public void kill() {
closeSocket(senderSocket);
closeSocket(listenerSocket);
closeSocket(broadCastListenerSocket);
}



public void run() {

try {

initializeBroadcastConnection();

while (true) {

//Recieving Datagramm
DatagramPacket rcv_packet = new DatagramPacket(rcv_message[writeBuffer], rcv_message[writeBuffer].length);
boolean NewMessageArrived = true;
try {
listenerSocket.receive(rcv_packet);
} catch (SocketTimeoutException e) {
NewMessageArrived = false;
}
//Watchdog
handleWatchDogTimer(State);

//TODO Delete String conversion
if (NewMessageArrived) {
dbg_message = new String(rcv_message[writeBuffer], 0, rcv_packet.getLength(), "US-ASCII");
Log.d(SpringAR.dataDebugLogPrefix, "" + rcv_packet.getAddress().getHostAddress() + ": " + dbg_message.trim() + " of " + rcv_packet.getLength() + "length ");
}

if (validatePackageSender(rcv_packet)) {
connectionStateMachine(rcv_message, rcv_packet);
}

//Sending Datagram
if (newDatagramToSend && hostIpAddress != null) {
//Log.d(SpringAR.protocollDebugLogPrefix, "Server sending: " + datagramToSend);
byte[] snd_message = datagramToSend.getBytes();

try {
snd_packet = packSendPackageByState(snd_message);
assert (snd_packet != null);
senderSocket.send(snd_packet);
newDatagramToSend = false;
} catch (IOException e1) {
e1.printStackTrace();
//causes Caused by: android.system.ErrnoException: sendto failed: EINVAL (Invalid argument)
Log.e(SpringAR.protocollDebugLogPrefix, "Server Error in State: " + State.name());
break;
}

}

}
} catch (IOException e1) {
e1.printStackTrace();
}
}

private void initializeBroadcastConnection() throws IOException {
ARDeviceAddress = InetAddress.getByName(comonUtils.getIPAddress(true));
senderSocket = getSocket(null, ARDeviceAddress, SpringAR.UDP_SERVER_PORT, null);
broadCastListenerSocket = getBroadcastListenerSocket();
listenerSocket = broadCastListenerSocket;
Log.d(SpringAR.protocollDebugLogPrefix, "initializeBroadcastConnection completed");
}


// handles management traffic like configurstion files
private void connectionStateMachine(byte[][] payload, DatagramPacket rcv_packet) throws IOException {
//Reset triggered by Host
if (comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveResetHeaderByte) != SpringAR.STRING_NOT_FOUND) {
State = SpringAR.comStates.STATE_resetCommunication;
}

Log.d(SpringAR.protocollDebugLogPrefix, "ConnectionStateMachine: " + State.name());
switch (State) {
case STATE_resetCommunication: {
messageCounter = 0;
listenerSocket = broadCastListenerSocket;
hostIpAddress = comonUtils.getBroadcastAddress(context);
senderSocket = getBroadcastSenderSocket(senderSocket);
setSendToSpringMessage(SpringAR.sendResetHeader);
State = SpringAR.comStates.STATE_broadCastHeader;

return;
}

case STATE_broadCastHeader: {
if (comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveHostReplyHeaderByte) != SpringAR.STRING_NOT_FOUND) {
Log.d(SpringAR.protocollDebugLogPrefix, " Host Reply Header recieved");
//Extract the hostIp
String hostIpAdressAsString = new String(payload[writeBuffer]);
hostIpAdressAsString = hostIpAdressAsString.replace(SpringAR.recieveHostReplyHeader, "").trim();
Log.d(SpringAR.dataDebugLogPrefix, hostIpAdressAsString);

hostIpAddress = InetAddress.getByName(hostIpAdressAsString);

//Set Connection from broadcast to target
ARDeviceAddress = InetAddress.getByName(comonUtils.getIPAddress(true));
Log.d(SpringAR.protocollDebugLogPrefix, " New Device Adress " + ARDeviceAddress);
senderSocket = getSocket(senderSocket, ARDeviceAddress, SpringAR.UDP_SERVER_PORT, hostIpAddress);
listenerSocket = senderSocket;
State = SpringAR.comStates.STATE_sendCFG;
return;
}


setSendToSpringMessage(SpringAR.sendBroadcasteHeader);

delayByMs(SpringAR.TIME_OUT_IN_BROADCAST);
return;
}

case STATE_sendCFG: {
if ( SpringAR.STRING_NOT_FOUND != comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveCFGHeaderByte )) {

State = SpringAR.comStates.STATE_sendRecieveData;
return;
}

setSendToSpringMessage(SpringAR.formConfigurationMessage());
return;
}

case STATE_sendRecieveData: {
if ( SpringAR.STRING_NOT_FOUND != comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveDataHeaderByte)) {
writeRecievedDataToBuffer(payload[writeBuffer], rcv_packet.getLength());
}
break;
}
default:
Log.d(SpringAR.protocollDebugLogPrefix, "Connection State Machine invalid state");

}


}

https://github.com/PicassoCT/arcore-android-sdk/blob/6c9b48a3d520e039cd48bc2af7354ccdec857736/arcore-android-sdk/samples/hello_ar/app/src/main/java/com/google/ar/core/examples/app/common/tcpClient/Server.java

所有测试均在家庭 WiFi 设置中进行,其中带有主机应用程序的桌面直接连接到 WiFi 路由器。

到目前为止,什么是有效的:该设备可以广播其存在。主机可以广播其配置。设备无法从 IP 到主机上的 IP 进行通信。双方都有固定的IP设置。

我可以通过主机应用程序与 App PacketSender 进行通信,并排除其故障。

我还构建了一个较小的调试循环,仅来回发送 udp 数据包,这也有效。

感谢您的宝贵时间

Captured Packages-Showing Broadcast going from the ARDevice to the Host-Application and a direktional Answer by the HostApplication, that is never recieved on the ARDevice

最佳答案

更改此行:

socket.setSoTimeout(30);

socket.setSoTimeout(1000);

这里有一个相当复杂的状态机,如果不查看日志就很难辨别发生了什么。我会这样总结你的状态机:

  1. 广播配置消息
  2. 花 30 毫秒监听响应
  3. 如果没有收到响应,则阻塞 SpringAR.TIME_OF_FRAME_IN_MS (未包含在您的代码中;我假设它是 1000 毫秒),然后循环回 #1
  4. 如果收到响应,请直接向对等方发送回复,然后转到#2

#4 是未发生的步骤。可能的原因(基于 Wireshark 转储)是 ARDevice 的响应需要 68 毫秒才能到达“主机”。你只给了它30毫秒。花费这么长时间的原因可能有很多,但这超出了您的问题范围。

关于java - 为什么我可以接收广播,但无法与应用程序中的特定套接字通信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52226729/

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