gpt4 book ai didi

java - 在 3G 上闪存到 Java 套接字丢失数据包

转载 作者:行者123 更新时间:2023-11-30 11:25:11 26 4
gpt4 key购买 nike

我正在尝试使用套接字将 flash android 应用程序与 java 通信,但是当应用程序通过 3G 连接时 - 许多包丢失(未收到)。

这是我的 Java 服务器:

public class SServer implements Runnable  {

protected int serverPort = 9070;
protected ServerSocket serverSocket = null;
protected boolean isStopped = false;
protected List<ClientRunnable> clients = new ArrayList<ClientRunnable>();
protected int msgCounter = 0;

public static void main(String args[]) {
SServer server = new SServer();
new Thread(server).start();
}

public void run(){

//init spam timer
new Timer().schedule(new TimerTask() {
@Override
public void run() {
for (ClientRunnable cr : clients) {
cr.send("Message " + msgCounter++);
cr.send("Message " + msgCounter++);
cr.send("Message " + msgCounter++);
}
}
}, 0, 2000);

openServerSocket();
while(! isStopped()){
Socket clientSocket = null;
try {
clientSocket = this.serverSocket.accept();
} catch (IOException e) {
if(isStopped()) {
System.out.println("Server Stopped."); return;
}
throw new RuntimeException("Error accepting client connection", e);
}
ClientRunnable cr = new ClientRunnable(clientSocket);
clients.add(cr);
new Thread(cr).start();
}
System.out.println("Server Stopped.") ;
}

private synchronized boolean isStopped() {
return this.isStopped;
}


private void openServerSocket() {
try {
this.serverSocket = new ServerSocket(this.serverPort);
System.out.println("Server Started.") ;
} catch (IOException e) {
throw new RuntimeException("Cannot open port 8080", e);
}
}

这是客户端线程:

public class ClientRunnable implements Runnable{

protected Socket clientSocket = null;
protected Boolean connected = false;
protected BufferedReader in = null;
protected PrintStream os = null;


public ClientRunnable(Socket clientSocket) {
this.clientSocket = clientSocket;
}

public void run() {

connected = true;

try {
//InputStream input = clientSocket.getInputStream();
in = new BufferedReader (new InputStreamReader(clientSocket.getInputStream(), "UTF-8" ));
os = new PrintStream(clientSocket.getOutputStream());

//read
//..


} catch (IOException e) {
onError(e);
connected = false;
closeConnection();
}
}

private void closeConnection() {
os.close();
//other closing code..
}

public void send(String data) {
try {
byte[] dataBytes = data.getBytes("UTF-8");
//will contain all bytes plus zery byte flash delimiter
byte[] allBytes = new byte[dataBytes.length + 1];
System.arraycopy(dataBytes, 0, allBytes, 0, dataBytes.length);
allBytes[allBytes.length-1] = (byte)0;
synchronized (this) {
Thread.sleep(50); //non 3G workaround
os.write(allBytes);
os.flush();
}
} catch (Exception e) {
e.printStackTrace();
onError(e);
}
}

public void onError(Exception ex) {
ex.printStackTrace();
}

请注意 Thread.sleep(50);在每次发送之前写入 - 修复了非常规非 3G 连接上的问题。但是当app运行在3G网络时,这个值肯定会高很多,而且有时还会出现漏包的情况。

这是我的 flex 客户端:

<?xml version="1.0" encoding="utf-8"?>

<fx:Script>
<![CDATA[
import spark.events.ViewNavigatorEvent;

private var _socket:Socket;
private var _host:String = "<MY HOST IP>";
private var _port:int = 9070;

protected function onViewActivate(event:ViewNavigatorEvent):void {
_socket = new Socket(_host, _port);
_socket.addEventListener(Event.CLOSE, function(e:Event):void{ ta.appendText("Close\n"); });
_socket.addEventListener(Event.CONNECT, function(e:Event):void{ ta.appendText("Connect\n"); });
_socket.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOErrorEvent):void{ ta.appendText("IO Error\n"); });
_socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function(e:IOErrorEvent):void{ ta.appendText("Security Error\n"); });
_socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
}

private function socketDataHandler(event:ProgressEvent):void {
var socket:Socket = event.target as Socket;
var str:String = socket.readUTFBytes(socket.bytesAvailable);
ta.appendText(str+"\n");
}

]]>
</fx:Script>

<s:VGroup width="100%" height="100%">
<s:TextArea id="ta" skinClass="spark.skins.mobile.TextAreaSkin" width="100%" height="100%" />
<s:Button label="Reconnect" click="_socket.connect(_host, _port)" />
</s:VGroup>

这就是它最终的样子:(注意顺序发送是有问题的,虽然有50ms的延迟)

enter image description here

如您所见,许多顺序消息未收到。增加延迟会有所帮助,但并非总是如此(而且作为解决方案也很糟糕)。

Flex 项目已上传HERE

Java项目上传HERE

最佳答案

我最近在 AS 和 Java 之间运行的套接字连接上遇到了类似的问题。我通过在 Java 中制作一个消息队列,向我的消息添加一个消息 ID,然后在发送队列中的下一条消息之前让 ActionScript 端使用 messageID 响应来解决它。这保证了相同的消息一遍又一遍地发出,直到 AS 响应它收到它。

关于java - 在 3G 上闪存到 Java 套接字丢失数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20412089/

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