Tcp和IP协议是很重要的内容,但是要理解这些协议最好的方式就是自己根据业务写一些demo,加深理解。
业务需求是:通过电脑端(网页或客户端形式)发送文件到Android的客户端,下面是使用UDP实现的一个简单的文件传输Demo,因UDP为不可靠传输,可能会丢包。
- 服务器端发送本地文件,代码如下:
package client;
import server.udp.UDPUtils;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
public class UDPClient {
private static final String SEND_FILE_PATH = "/Users/wangjie/Documents/123.mp4";
public static void main(String[] args){
long startTime = System.currentTimeMillis();
byte[] buf = new byte[UDPUtils.BUFFER_SIZE];
byte[] receiveBuf = new byte[1];
RandomAccessFile accessFile = null;
DatagramPacket dpk = null;
DatagramSocket dsk = null;
int readSize = -1;
try {
accessFile = new RandomAccessFile(SEND_FILE_PATH,"r");
// dpk = new DatagramPacket(buf, buf.length,new InetSocketAddress(InetAddress.getByName("localhost"), UDPUtils.PORT + 1));
dpk = new DatagramPacket(buf, buf.length,new InetSocketAddress(InetAddress.getByName("192.168.1.119"), UDPUtils.PORT + 1));
dsk = new DatagramSocket(UDPUtils.PORT);
int sendCount = 0;
while((readSize = accessFile.read(buf,0,buf.length)) != -1){
System.out.println("readSize:"+readSize);
dpk.setData(buf, 0, readSize);
dsk.send(dpk);
// wait server response
{
while(true){
dpk.setData(receiveBuf, 0, receiveBuf.length);
dsk.receive(dpk);
// confirm server receive
if(!UDPUtils.isEqualsByteArray(UDPUtils.successData,receiveBuf,dpk.getLength())){
System.out.println("resend ...");
dpk.setData(buf, 0, readSize);
dsk.send(dpk);
}else
break;
}
}
System.out.println("send count of "+(++sendCount)+"!");
}
// send exit wait server response
while(true){
System.out.println("client send exit message ....");
dpk.setData(UDPUtils.exitData,0,UDPUtils.exitData.length);
dsk.send(dpk);
dpk.setData(receiveBuf,0,receiveBuf.length);
dsk.receive(dpk);
// byte[] receiveData = dpk.getData();
if(!UDPUtils.isEqualsByteArray(UDPUtils.exitData, receiveBuf, dpk.getLength())){
System.out.println("client Resend exit message ....");
dsk.send(dpk);
}else
break;
}
}catch (Exception e) {
e.printStackTrace();
} finally{
try {
if(accessFile != null)
accessFile.close();
if(dsk != null)
dsk.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
System.out.println("time:"+(endTime - startTime));
}
}
- 客户端接收文件存到本地,代码如下:
package cn.studyou.androidsocket;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
public class UDPReceiveFileActivity extends Activity {
private String localUrl;
private static final String FILE_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + "/VideoCache/";
private static final String SAVE_FILE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/VideoCache/";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_udpfile_mplayer);
Log.e("FILE_DIR", FILE_DIR);
new Thread(new Runnable() {
@Override
public void run() {
receiveFile();
}
}).start();
}
public void receiveFile() {
byte[] buf = new byte[UDPUtils.BUFFER_SIZE];
DatagramPacket dpk = null;
DatagramSocket dsk = null;
BufferedOutputStream bos = null;
try {
InetAddress loc = InetAddress.getByName("192.168.1.107");
dpk = new DatagramPacket(buf, buf.length, new InetSocketAddress(loc, UDPUtils.PORT));
dsk = new DatagramSocket(UDPUtils.PORT + 1);
if (localUrl == null) {
localUrl = SAVE_FILE_PATH + "1235.mp4";
}
File cacheFile = new File(localUrl);
if (!cacheFile.exists()) {
cacheFile.getParentFile().mkdirs();
cacheFile.createNewFile();
}
bos = new BufferedOutputStream(new FileOutputStream(localUrl));
System.out.println("wait client ....");
dsk.receive(dpk);
System.out.println("wait clientq ....");
int readSize = 0;
int readCount = 0;
int flushSize = 0;
while ((readSize = dpk.getLength()) != 0) {
// validate client send exit flag
if (UDPUtils.isEqualsByteArray(UDPUtils.exitData, buf, readSize)) {
System.out.println("server exit ...");
// send exit flag
dpk.setData(UDPUtils.exitData, 0, UDPUtils.exitData.length);
dsk.send(dpk);
break;
}
bos.write(buf, 0, readSize);
if (++flushSize % 1000 == 0) {
flushSize = 0;
bos.flush();
}
dpk.setData(UDPUtils.successData, 0, UDPUtils.successData.length);
dsk.send(dpk);
dpk.setData(buf, 0, buf.length);
System.out.println("receive count of " + (++readCount) + " !");
dsk.receive(dpk);
}
// last flush
bos.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bos != null)
bos.close();
if (dsk != null)
dsk.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}