Android TCP 多播丢失消息
Android TCP multicast missing message
我使用 asynctask 构建了一个 TCP 多播聊天应用程序。
我也在尝试按 FIFO 和因果顺序对消息进行排序。
但是,当我尝试同时发送大量消息进行测试时,它会漏掉一些消息,但我找不到原因。
我已经尽我所能来提高程序的性能,因为我认为性能可能是原因。但仍然有同样的问题。
我附上了我的代码的一些重要部分。
最重要的是,
private class ServerTask extends AsyncTask<ServerSocket, String, Void> {
@Override
protected Void doInBackground(ServerSocket... sockets){
ServerSocket serverSocket = sockets[0];
Socket socket = new Socket();
try {
while(true) {
socket = serverSocket.accept();
InputStream inputstream = socket.getInputStream();
DataInputStream in = new DataInputStream(new BufferedInputStream(inputstream));
String msg = ""+in.readUTF();
String time = ""+in.readUTF();
String temp = time+"||"+msg;
publishProgress(temp);
in.close();
}} catch (IOException e) {
e.printStackTrace();
} finally{
try {
socket.close();
serverSocket.close();////
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
这是onProgressUpdate。
protected void onProgressUpdate(String...strings) {
/*
* The following code displays what is received in doInBackground().
*/
String strReceived = strings[0].trim();
TextView remoteTextView = (TextView) findViewById(R.id.textView1);
remoteTextView.append(strReceived + "\t\n");
try {
sequencer(strReceived);
} catch (ParseException e) {
e.printStackTrace();
}
return;
}
}
..
private class ClientTask extends AsyncTask<String, Void, Void> {
@Override
protected Void doInBackground(String... msgs) {
Date currentDate= new Date();
Timestamp time = new Timestamp(currentDate.getTime());
Message temp = new Message(myPort, msgs[0], time);////
try {
for(int i = 0; i <= 2; i++) {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(InetAddress.getByAddress(new byte[]{10, 0, 2, 2}),
Integer.parseInt(REMOTE_PORTS[i])), 1000);
socket.setTcpNoDelay(true);
OutputStream outputStream = socket.getOutputStream();
DataOutputStream o = new DataOutputStream(new BufferedOutputStream(outputStream));
o.writeUTF(msgs[0]);
o.writeUTF(""+time);
o.flush();////
socket.close();
}
}
catch (UnknownHostException e) {
Log.e(TAG, "ClientTask UnknownHostException");
} catch (IOException e) {
Log.e(TAG, "ClientTask socket IOException");
}
return null;
}
你能找到导致问题的部分吗?
排序/排队/确认所有这些都是 TCP 的一部分,因此它由协议本身完成,因此您不需要从代码中明确地执行所有这些操作。您的代码中仍有一些部分可以改进。喜欢:
String time = received.split("\|\|")[0];
String msgToSend = received.split("\|\|")[1];
//Instead of doing this, its better to do this:
String peices[]=received.split("\|\|");
String msgToSend=peices[1];
String time=peices[0]
您还可以使用日志检查是否收到所有原始消息,以及在解析过程中消息是否丢失:
Log.d("RAW_MESSAGE","Message Received: "+temp); //in your doInBackground
如果您在该日志中收到了您发送的所有消息,那么协议或 sending/receiving 过程没有任何问题,而是您在处理消息时出现了问题。同样对于这些类型的用例,请尝试使用服务组件而不是 AsyncTask。
希望对您有所帮助。
首先,多播是基于 UDP,而不是 TCP。
如果你想创建一个多播应用程序,你应该使用 multicastsocket
http://developer.android.com/reference/java/net/MulticastSocket.html
我使用 asynctask 构建了一个 TCP 多播聊天应用程序。 我也在尝试按 FIFO 和因果顺序对消息进行排序。
但是,当我尝试同时发送大量消息进行测试时,它会漏掉一些消息,但我找不到原因。 我已经尽我所能来提高程序的性能,因为我认为性能可能是原因。但仍然有同样的问题。 我附上了我的代码的一些重要部分。 最重要的是,
private class ServerTask extends AsyncTask<ServerSocket, String, Void> {
@Override
protected Void doInBackground(ServerSocket... sockets){
ServerSocket serverSocket = sockets[0];
Socket socket = new Socket();
try {
while(true) {
socket = serverSocket.accept();
InputStream inputstream = socket.getInputStream();
DataInputStream in = new DataInputStream(new BufferedInputStream(inputstream));
String msg = ""+in.readUTF();
String time = ""+in.readUTF();
String temp = time+"||"+msg;
publishProgress(temp);
in.close();
}} catch (IOException e) {
e.printStackTrace();
} finally{
try {
socket.close();
serverSocket.close();////
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
这是onProgressUpdate。
protected void onProgressUpdate(String...strings) {
/*
* The following code displays what is received in doInBackground().
*/
String strReceived = strings[0].trim();
TextView remoteTextView = (TextView) findViewById(R.id.textView1);
remoteTextView.append(strReceived + "\t\n");
try {
sequencer(strReceived);
} catch (ParseException e) {
e.printStackTrace();
}
return;
}
}
..
private class ClientTask extends AsyncTask<String, Void, Void> {
@Override
protected Void doInBackground(String... msgs) {
Date currentDate= new Date();
Timestamp time = new Timestamp(currentDate.getTime());
Message temp = new Message(myPort, msgs[0], time);////
try {
for(int i = 0; i <= 2; i++) {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(InetAddress.getByAddress(new byte[]{10, 0, 2, 2}),
Integer.parseInt(REMOTE_PORTS[i])), 1000);
socket.setTcpNoDelay(true);
OutputStream outputStream = socket.getOutputStream();
DataOutputStream o = new DataOutputStream(new BufferedOutputStream(outputStream));
o.writeUTF(msgs[0]);
o.writeUTF(""+time);
o.flush();////
socket.close();
}
}
catch (UnknownHostException e) {
Log.e(TAG, "ClientTask UnknownHostException");
} catch (IOException e) {
Log.e(TAG, "ClientTask socket IOException");
}
return null;
}
你能找到导致问题的部分吗?
排序/排队/确认所有这些都是 TCP 的一部分,因此它由协议本身完成,因此您不需要从代码中明确地执行所有这些操作。您的代码中仍有一些部分可以改进。喜欢:
String time = received.split("\|\|")[0];
String msgToSend = received.split("\|\|")[1];
//Instead of doing this, its better to do this:
String peices[]=received.split("\|\|");
String msgToSend=peices[1];
String time=peices[0]
您还可以使用日志检查是否收到所有原始消息,以及在解析过程中消息是否丢失:
Log.d("RAW_MESSAGE","Message Received: "+temp); //in your doInBackground
如果您在该日志中收到了您发送的所有消息,那么协议或 sending/receiving 过程没有任何问题,而是您在处理消息时出现了问题。同样对于这些类型的用例,请尝试使用服务组件而不是 AsyncTask。
希望对您有所帮助。
首先,多播是基于 UDP,而不是 TCP。
如果你想创建一个多播应用程序,你应该使用 multicastsocket
http://developer.android.com/reference/java/net/MulticastSocket.html