⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 servertcpthread.java

📁 局域网飞鸽传输
💻 JAVA
字号:
/**
  * @(#)logic.ServerTCPThread.java  2008-10-9  
  * Copy Right Information	: Tarena
  * Project					: IPMsg
  * JDK version used		: jdk1.6.4
  * Comments				: ServerSocket网络服务端。
  * Version					: 1.0
  * Sr	Date		Modified By		Why & What is modified
  * 1.	2008-10-9 	小猪     		新建
  **/
package logic;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;

import data.FSMessage;

 /**
 * ServerSocket网络服务端。<br>
 * 主要负责传送文件。
 * 2008-10-9
 * @author		达内科技[Tarena Training Group]
 * @version	1.0
 * @since		JDK1.6(建议) 
 */
public class ServerTCPThread extends Thread {
	
	/** 服务器ServerSocket */
	private ServerSocket server = null;
	/** 程序是否运行中 */
	private boolean isRun = false;
	/** 客户端连接进程 */
	private Vector<ClientThread> clientThread = new Vector<ClientThread>();
	/** 获取发送列表 */
	private UDPThread udp = null;

	public ServerTCPThread(UDPThread udp,int port) throws IOException {
		server = new ServerSocket(port);
		this.udp = udp;
	}
	
	@Override
	public void run() {
		isRun = true;
		try {
			while(isRun && server!=null){
				Socket client = server.accept();
				ClientThread ct = new ClientThread(client);
				clientThread.add(ct);
				ct.start();
			}
		} catch (IOException e) {
			System.out.println("服务器接受客户端错误:"+e.getMessage());
			closeServer();
		}
		
	}
	
	/**
	 * 关闭到客户端的连接和服务器。
	 */
	public void closeServer(){
		isRun = false;
		for(ClientThread ct:clientThread)
			ct.letClientQuit(91,"服务端关闭");
		try {
			if(server!=null)
				server.close();
			server = null;
		} catch (IOException e) {
			System.out.println("关闭TCP的ServerSocket时错误!-->"+e.getMessage());
		}
	}
	
	/**
	 * 客户端线程类。
	 * 2008-10-5
	 * @author		达内科技[Tarena Training Group]
	 * @version	1.0
	 * @since		JDK1.6(建议) 
	 */
	private class ClientThread extends Thread{
		/** 客户端 */
		private Socket client = null;
		/** 线程的输出流 */
		private ObjectOutputStream oos = null;
		/** 线程的输入流 */
		private ObjectInputStream ois = null;
		/** 是否暂停发送 */
		private boolean isPauseSend = false;
		/** 是否停止发送 */
		private boolean isStopSend = false;
		/** 客户端是否运行 */  
		private boolean isClientRun = true;
		/** 客户端发送线程 */
		private WriteThread writeThread = null;
		
		public ClientThread(Socket client) {
			try {
				this.client = client;
				ois = new ObjectInputStream(new BufferedInputStream(new DataInputStream(client.getInputStream())));
				oos = new ObjectOutputStream(new BufferedOutputStream(new DataOutputStream(client.getOutputStream())));
			} catch (IOException e) {
				System.out.println("打开客户端的连接错误:"+e.getMessage());
				closeClient();
			}
		}
		
		/**
		 * 消息内容:
		 * 类型说明:
		 * 10:客户端发送文件地址
		 * 11:客户端发送的地址有误,不予响应
		 * 20:服务端发送相对目录地址到客户端,客户端接到信息创建目录
		 * 21:服务端发送相对文件地址到客户端,客户端接到信息创建文件
		 * 22:开始发送数据,发送文件长度
		 * 31:数据发送完成
		 * 40:客户端请求暂停发送
		 * 41:客户端请求继续发送
		 * 42:服务端取消发送
		 * 90:客户端退出
		 * 91:服务端退出
		 * 92:请求数据全部发送完成.
		 */
		@Override
		public void run() {
			try {
				while(isClientRun && ois!=null && oos!=null){
					Object obj = ois.readObject();
					if(obj instanceof FSMessage){
						FSMessage message = (FSMessage)obj;
						int type = message.getType();
						switch (type) {
						case 10:
							writeThread = new WriteThread(message.getObject());
							writeThread.start();
							break;
						case 40:
							isPauseSend = true;
							break;
						case 41:
							writeThread.interrupt();
							break;
						case 90:
							dealClientQuit();
							break;
						}
					}
				}
			} catch (IOException e) {
				System.out.println("和客户端的连接发生错误:"+e.getMessage());
				closeClient();
			} catch (ClassNotFoundException e) {
				System.out.println("和客户端的连接发生错误:"+e.getMessage());
				closeClient();
			}
		}
		
		private class WriteThread extends Thread{
			/** 数据路径 */
			private String path = null;
			public WriteThread(Object obj) {
				path = obj.toString();
			}
			@Override
			public void run() {
				try {
					if(client==null) return;
					String ip = client.getInetAddress().getHostAddress();
					File file = new File(path);
					String parent = file.getParent();
					if(file!=null && file.exists() && file.canRead() && udp.isAllowSend(ip, path)){
						send(file,parent);
						letClientQuit(92,"请求的数据发送完成!");
					}else{
						oos.writeObject(new FSMessage(11,"嘎嘎你发送的数据不予理睬!"));
						oos.flush();
						letClientQuit(91, "强制退出!传输完成");
					}
				} catch (IOException e) {
					System.out.println("发送数据时发生错误:"+e.getMessage());
				}
			}
			
			/**
			 * 发送文件或路径
			 * @param file 文件
			 * @param parent 该文件的父路径
			 * @throws IOException 发送数据时抛出该异常。
			 */
			private void send(File file,String parent) throws IOException{
				if(file!=null && file.exists() && file.canRead() && !file.getName().equals("")){//文件名不为空
					if(file.isDirectory()){
						oos.writeObject(new FSMessage(20,file.getAbsolutePath().substring(parent.length())));
						oos.flush();
						for(File xfile:file.listFiles())
							send(xfile,parent);
					}
					if(file.isFile()){
						oos.writeObject(new FSMessage(21,file.getAbsolutePath().substring(parent.length())));
						oos.flush();
						oos.writeObject(new FSMessage(22,file.length()));
						oos.flush();
						DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
						int readlen = 0;
						do{
							try {//暂停发送
								if(isPauseSend)
									join();
							} catch (InterruptedException e) {
								System.out.println("继续发送数据");
								isPauseSend = false;
							}
							if(isStopSend)//停止发送
								break;
							byte[] data = new byte[1024];
							readlen = dis.read(data);
							if(readlen==-1)
								break;
							//oos.writeObject(new FSMessage(22,data));
							oos.write(data,0,readlen);
							oos.flush();
							data = null;
						}while(true);
						dis.close();
						dis = null;
						if(!isStopSend){
							oos.writeObject(new FSMessage(31,file.getName()));
							oos.flush();
						}
					}
				}else{//file不为空end
					oos.writeObject(new FSMessage(11,"该文件不可发送"));
					oos.flush();
					letClientQuit(91, "强制退出!传输完成");
				}
			}
		}
		
		/**
		 * 使得客户端退出。
		 */
		public void letClientQuit(int type,String msg){
			FSMessage message = new FSMessage(type,msg);
			//new WriteThread(message).start();
			//防止空指针异常!如果启用单独线程关闭到服务端的连接时很可能发生空指针异常。
			try {
				oos.writeObject(message);
				oos.flush();
			} catch (IOException e) {}
			closeClient();
		}
		
		/**
		 * 客户端退出。
		 */
		private void dealClientQuit(){
			isClientRun = false;
			isStopSend = true;
			closeClient();
		}
		
		/**
		 * 关闭到客户端的连接。
		 */
		private void closeClient(){
			try {
				clientThread.remove(this);
			} catch (RuntimeException e1) {}
			try {
				if(oos!=null)
					oos.close();oos = null;
				if(ois!=null)
					ois.close();ois = null;
				if(client!=null)
					client.close();client = null;
			} catch (IOException e) {}
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -