团队博客12
通过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; } } }