• 团队博客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;
    			}
    		}
    		
    	}
    	
    

      

  • 相关阅读:
    CSS 中 Position relative 和 absolute区别
    感受到LDT的好处
    Map数据结构
    break和continue
    vue的ref属性
    css小样式
    搭建vue开发环境
    setTimeout和clearTimeout
    垂直居中
    vertical-align 属性
  • 原文地址:https://www.cnblogs.com/XJXYJ/p/5866778.html
Copyright © 2020-2023  润新知