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

  

posted @ 2016-09-12 23:06  JYJe族  阅读(99)  评论(0编辑  收藏  举报