我已经设法编写一个异步类,通过广播发送图片并等待客户端反向ack,然后发送未收到的包... 我面临的问题是,发送1MB图片需要很长时间(1分钟aprox)来完成只有两部手机通过wifi相互连接。这是我的代码(对不起长代码)
SENDER CLASS
B
接收课程
public class SenderBroadcastAsyncTask extends AsyncTask<File, Integer, String> {
Context context;
public SenderBroadcastAsyncTask(Context context) {
this.context = context.getApplicationContext();
}
@Override
protected String doInBackground(File... imagen) {
Log.d("SENDER","INICIANDO EL SOCKET PARA ENVIAR");
InetAddress group = null;
try {
group = InetAddress.getByName("192.168.49.255");
} catch (UnknownHostException e) {
e.printStackTrace();
}
int port =1212;
DatagramSocket socket = null;
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
try {
socket.setBroadcast(true);
} catch (SocketException e) {
e.printStackTrace();
}
DatagramSocket rsocket = null;
try {
rsocket = new DatagramSocket(1513);
} catch (SocketException e) {
e.printStackTrace();
}
try {
rsocket.setSoTimeout(2000);
} catch (SocketException e) {
e.printStackTrace();
}
for (File i:imagen) {
Bitmap bitmap = BitmapFactory.decodeFile(i.getAbsolutePath());
ByteArrayOutputStream stream2 = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream2);
byte[] prebuf = stream2.toByteArray();
mandar(prebuf, rsocket, socket, group, port);
}
return "ok";
}
public void mandar(byte[] prebuf,DatagramSocket rsocket,DatagramSocket socket,InetAddress group,int port) {
int DATAGRAM_MAX_SIZE = 50*1024;
int cantidadpedazos = (int) Math.ceil(prebuf.length / (float) DATAGRAM_MAX_SIZE);
Log.d("Pedazos", Integer.toString(cantidadpedazos));
//Loop peaces
for (int i = 1; i <= cantidadpedazos; i++) {
enviar(i,socket,group,port,prebuf,DATAGRAM_MAX_SIZE,cantidadpedazos);
}
////FINAL DONE
String message_to_send = "DONE";
byte[] ultimo = message_to_send.getBytes();
DatagramPacket ultimopaquete = new DatagramPacket(ultimo, ultimo.length, group, port);
try {
socket.send(ultimopaquete);
} catch (IOException e) {
e.printStackTrace();
}
/*AFTER DONE WAIT FOR INVERSE ACK OF NUMERED PACKETS*/
boolean mandarfaltan = false;
boolean ack = false;
int countertoend=0;
boolean cancelcheck = false;
while (!ack) {
byte[] recibir = new byte[5];
DatagramPacket pkgrecibir = new DatagramPacket(recibir, 0, recibir.length);
Log.d("UDP", "S: Receiving...");
try {
rsocket.receive(pkgrecibir);
} catch (SocketTimeoutException e) {
Log.d("timeout","TIMEOUT EXCEPTION");
if (mandarfaltan) {
try {
socket.send(ultimopaquete);
} catch (IOException q) {
q.printStackTrace();
}
if (countertoend ==7)
{
Log.d("error","timeout error no response to done");
socket.close();
rsocket.close();
break;
}
cancelcheck = true;
countertoend++;
} else {
Log.d("ACK", "TIMEOUT CANELING PASSING TO DONE");
socket.close();
rsocket.close();
break;
}
} catch (IOException e) {
e.printStackTrace();
}
mandarfaltan = true;
if (!cancelcheck) {
String faltast = new String(pkgrecibir.getData()).trim();
Integer faltaint = Integer.parseInt(faltast); ////euivalent to for i
enviar(faltaint, socket, group, port, prebuf, DATAGRAM_MAX_SIZE, cantidadpedazos);
if (new String(pkgrecibir.getData()).trim().contains("DONE")) {
Log.d("ACK", "Received" + " " + new String(pkgrecibir.getData()).trim());
ack = true;
}
}
cancelcheck = false;
}
}
public void enviar(int i,DatagramSocket socket,InetAddress group,int port,byte[] prebuf,int DATAGRAM_MAX_SIZE,int cantidadpedazos){
//for (int i = 1; i <= cantidadpedazos; i++) {
////EN cada interaccion del for clono el array con las ip q recibiran el paquete
//ArrayList<String> finallist = (ArrayList<String>) tosend.clone();
String final_str = null;
String counter_str = Integer.toString(i);
int len = counter_str.length();
byte[] final_strbyte = new byte[5];
Log.d("HEADER", counter_str + " TAMANO " + Integer.toString(len));
switch (len) {
case 1:
final_str = "0000" + Integer.toString(i);
final_strbyte = final_str.getBytes();
break;
case 2:
final_str = "000" + counter_str;
final_strbyte = final_str.getBytes();
break;
case 3:
final_str = "00" + counter_str;
final_strbyte = final_str.getBytes();
break;
case 4:
final_str = "0" + counter_str;
final_strbyte = final_str.getBytes();
break;
case 5:
final_str = counter_str;
final_strbyte = final_str.getBytes();
break;
}
byte[] slice, imagetosend;
DatagramPacket packet;
if (i == 1) {
slice = Arrays.copyOfRange(prebuf, 0, i * DATAGRAM_MAX_SIZE);
imagetosend = new byte[slice.length + 5];
for (int s = 0; s < 5; s++) {
imagetosend[s] = final_strbyte[s];
}
for (int s = 0; s < slice.length; s++) {
imagetosend[s + 5] = slice[s];
}
packet = new DatagramPacket(imagetosend, imagetosend.length, group, port);
for (int s = 0; s < 1; s++) {
try {
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
} else if (i == cantidadpedazos) {
slice = Arrays.copyOfRange(prebuf, (i - 1) * DATAGRAM_MAX_SIZE, prebuf.length);
imagetosend = new byte[slice.length + 5];
for (int s = 0; s < 5; s++) {
imagetosend[s] = final_strbyte[s];
}
for (int s = 0; s < slice.length; s++) {
imagetosend[s + 5] = slice[s];
}
packet = new DatagramPacket(imagetosend, imagetosend.length, group, port);
for (int s = 0; s < 2; s++) {
try {
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
slice = Arrays.copyOfRange(prebuf, ((i - 1) * DATAGRAM_MAX_SIZE), i * DATAGRAM_MAX_SIZE);
imagetosend = new byte[slice.length + 5];
for (int s = 0; s < 5; s++) {
imagetosend[s] = final_strbyte[s];
}
for (int s = 0; s < slice.length; s++) {
imagetosend[s + 5] = slice[s];
}
packet = new DatagramPacket(imagetosend, imagetosend.length, group, port);
for (int s = 0; s < 2; s++) {
try {
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
如果有人可以检查并让我知道可能导致文件接收延迟的原因,我真的很感激。 (这是udp它想快点) 提前致谢