通过Socket编程(多线程)传递文件
SendThread = new Thread(sendRunnable);
SendThread.start();
public Runnable sendRunnable = new Runnable() {
@Override
public void run() {
Socket socket = null;
InetAddress address = socket.getInetAddress();
try{
socket = new Socket("localhost", 8888);
//创建socket,指定接收端的IP地址和端口号
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream(file);
int count = fis.available();
byte[] filedata = new byte[count];
//将选中的文件存储在内存中
fis.read(filedata);
String string = file.getName().toString()+"."+filedata.length+".";
byte[] str = string.getBytes(Charset.forName("UTF-8"));
byte[] data = new byte[count+str.length];
//将存储文件信息的数组和存储文件内容的数组组合为一个新的数组
System.arraycopy(str, 0, data, 0, str.length);
System.arraycopy(filedata, 0, data, str.length, filedata.length);
//发送出消息,格式为:“文件名:文件大小(字节数):文件内容”
os.write(data);
os.flush();
//关闭相关资源
fis.close();
os.close();
Looper.prepare();
Toast.makeText(MobileActivity.this, "发送成功!", Toast.LENGTH_LONG).show();
//提示发送成功
Looper.loop();
}catch(UnknownHostException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
};
服务器端:
ServerSocket serverSocket = null;
int LocalListenPort = 8888;
Thread listenThread = null;
public int m_fileLen = 0;
public String m_filename = null;
FileOutputStream fos = null;
File SDPath = null;
File newFile = null;
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
try{
//关闭监听套接字
serverSocket.close();
//终止线程
listenThread.interrupt();
}catch(IOException e){
e.printStackTrace();
}
}
@Override
@SuppressWarnings("deprecation")
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
//SD卡默认目录
SDPath = Environment.getExternalStorageDirectory();
listenThread = new Thread(null, listener, "listenThread");
listenThread.start();//启动监听线程
}
public Runnable listener = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try{
//实例化监听套接字,使他监听指定端口
serverSocket = new ServerSocket(LocalListenPort);
//循环监听
while(!Thread.interrupted()){
//使用accept()放啊发接受客户端发送的请求
Socket socket = serverSocket.accept();
receiveDataRunnable recThread = new receiveDataRunnable();
recThread.setSocket(socket);
Thread thread = new Thread(recThread);
thread.start();
}
}catch(IOException e){
e.printStackTrace();
}
}
};
@SuppressLint("NewApi")
public class receiveDataRunnable implements Runnable{
private boolean ReceiveEnd = false;
private Socket m_socket;
public void setSocket(Socket socket) {
m_socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
InputStream is = null;
try{
is = m_socket.getInputStream();
}catch(IOException e2){
e2.printStackTrace();
}
while(ReceiveEnd == false){
try{
int count = 0;
//返回的实际刻度字节数,当前消息的总大小
while(count == 0){
count = is.available();
}
byte readBuffer [] = new byte[count];
int temp = 0;
temp = is.read(readBuffer, 0, readBuffer.length);
if(temp == -1){
continue;
}
if(m_fileLen == 0 && m_filename == null){
//是否为第一次接受到数据
String revText = new String(readBuffer, Charset.forName("UTF-8"));
String[] sep = revText.split(":");
m_filename = sep[0];
m_fileLen = Integer.parseInt(sep[1]);
if(sep.length>2 && !sep[2].equals("")){
//接受的消息中有含有文件内容,统计非文件内容所占的字节
String infoStr = sep[0]+":"+sep[1]+":";
int infoByteLen = infoStr.getBytes(Charset.forName("UTF-8")).length;
int fileLen = readBuffer.length - infoByteLen;
newFile = new File(SDPath, m_filename);
newFile.createNewFile();
fos = new FileOutputStream(newFile);
if(m_fileLen <= fileLen){
fos.write(readBuffer, infoByteLen, m_fileLen);
fos.flush();
fos.close();
fos = null;
m_filename = null;
m_fileLen = 0;
ReceiveEnd = true;
//文件接受完成,将文件名传到Activity中
/*MobileActivity.GetFileName(newFile.getPath().toString())*/
}
else{
//表示这次接收的消息并未包含全部的文件内容
fos.write(readBuffer, infoByteLen, fileLen);
m_fileLen -= fileLen;
}
}
}
else{
//不是第一次接受,继续结束当前发过来的剩余内容
if(readBuffer.length<m_fileLen){
//当前消息不包含全部的剩余文件内容
fos.write(readBuffer, 0, readBuffer.length);
}
else{
fos.write(readBuffer, 0, m_fileLen);
}
m_fileLen -= temp;
//判断是否接受完成
if(m_fileLen <= 0){
//文件接受完成
fos.flush();
fos.close();
fos = null;
m_filename = null;
m_fileLen = 0;
ReceiveEnd = true;
//将文件名传到Activity中
//MobileActivity.GetFileName(newFile.getPath().toString());
}
}
}catch(IOException e){
try{
m_socket.shutdownInput();
m_socket.close();
}catch(IOException e1){
e1.printStackTrace();
return;
}
e.printStackTrace();
}
}
//关闭输入流及客户端套接字
try{
is.close();
m_socket.close();
}catch(IOException e){
e.printStackTrace();
return;
}
}
}