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

📄 paintserver.java

📁 一个简易的java画图软件
💻 JAVA
字号:
package net;

import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Iterator;

import app.Application;

import draw.View;

/**
 * 服务器,控制着服务器接收器和服务器发送器
 * 
 * @author Thihy
 * 
 */
public class PaintServer extends Thread {
	public int clientNum = 0;
	HashMap<String, String> userNames = new HashMap<String, String>();
	HashMap<String, ServerSend> clients = new HashMap<String, ServerSend>();

	ServerSocket serverSocket;
	protected boolean shouldShutdown = false;
	protected View view;
	protected String errorInfo = null;

	/**
	 * 为View建立一个响应的Sever。每个View只能有一个Sever, 但是可以有多个Client。
	 * 
	 * @param view  与服务器关联的View
	 */
	public PaintServer(View view) {
		this.view = view;

	}
	/**
	 * 获取连接失败的错误信息
	 * @return 失败的错误信息
	 */
	public String getErrorInfo() {
		return errorInfo;
	}

	/**
	 * 创建一个服务器,如果失败返回false。
	 * 
	 * 会检测一些常见的错误: 如端口被占用等。
	 * 
	 * @param port 建立服务器的端口
	 * 
	 * @return 如果失败返回false。
	 */
	public boolean createServer(int port) {
		try {
			serverSocket = new ServerSocket(port);
			userNames.put("Server", "服务器");
		} catch (BindException e) {
			System.out.println(e.getMessage());
			String mesg = e.getMessage();
			if (mesg.indexOf("already") != -1 && mesg.indexOf("use") != -1) {
				System.out.println("端口已经被占用。");
				errorInfo = "端口已经被占用。";
			}
			return false;
		} catch (IOException e) {
			errorInfo = "通信错误。";
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 修改指定的netName的客户端的用户名。
	 * 
	 * @param netName 网络名称
	 * @param userName 新的用户名
	 */
	private void changeUserName(String netName, String userName) {
		if (userName.length() > 0 && userName.indexOf(':') == -1
				&& userNames.containsKey(netName)) {
			String oldUserName = userNames.get(netName);
			if (oldUserName != null)
				userNames.put(netName, userName);
			sendNotice(oldUserName + " 用户已经更名为 " + userName);
		} else {
			if (Application.DEBUG > 3) {
				System.out.println("用户名的指定有误。");
			}
		}
	}

	/**
	 * 从客户端netName接送到一个消息,如果是更改用户名,则 由服务器修改后向所有客户端发送更改消息。
	 * 
	 * @param netMes 发送的消息
	 * @param netName 发送者的网络名称
	 */
	public void receiveMessage(Object object, String netName) {
		if (!userNames.containsKey(netName)) {
			if (Application.DEBUG > 3)
				System.out.println("非法的发送信息:一个没有注册的客户端已经发送");
			return;
		}
		NetMessage netMes = null;
		if (object instanceof NetMessage) {
			netMes = (NetMessage) object;
		} else {
			if (Application.DEBUG > 3) {
				System.out.println("客户端接收到一个非消息对象");
			}
			return;
		}

		if (netMes.messageHeader.equals(NetMessage.MES_SET_USER_NAME)) {
			Object obj = netMes.messageContent;
			if (obj != null && obj instanceof String) {
				String userName = (String) obj;
				/*
				 * int index=str.indexOf(':'); if(index!=-1 &&
				 * index<str.length()-1){//第一个是发送者
				 * 网络名(server指定),第二个是发送者的用户名(用户自定义) String
				 * netName=str.substring(0,index); String
				 * userName=str.substring(index+1);
				 */
				changeUserName(netName, userName);
				// }
			}
		} else if (netMes.messageHeader.equals(NetMessage.MES_SHUTDOWN)) {// 这是客户端断开后
			// ,
			// serverReceive发的关闭消息
			Object obj = netMes.messageContent;
			if (obj != null && obj instanceof String) {
				String userName =userNames.get(netName);
				sendNotice(userName + " 用户离开了");
			}
		} else {
			if (netMes.messageHeader.equals(NetMessage.MES_CHAT)) {
				String userName = userNames.get(netName);
				userName = (userName == null) ? netName : userName;
				netMes.messageContent = userName + ":" + netMes.messageContent;
			}
			// TODO 向view和其他所有客户端发送消息
			view.receiveMessage(netMes);
			sendMessage(netMes, netName);
		}

	}

	/**
	 * 服务器发送通知
	 * @param string
	 */
	private void sendNotice(String string) {
		NetMessage netMes = new NetMessage(NetMessage.MES_SERVER_NOTICE, string);
		view.receiveMessage(netMes);
		sendMessage(netMes, "Server");
	}

	/**
	 * 服务器向所有客户端发送消息
	 * @param netMes 发送的消息
	 */
	public void sendMessage(NetMessage netMes) {// 此画布要求服务器向所有客户端发送消息
		if (netMes.messageHeader.equals(NetMessage.MES_SET_USER_NAME)) {
			Object obj = netMes.messageContent;
			if (obj != null && obj instanceof String) {
				String userName = (String) obj;
				changeUserName("Server", userName);
			}
		} else {
			if (netMes.messageHeader.equals(NetMessage.MES_SHUTDOWN))
				shouldShutdown = true;

			if (netMes.messageHeader.equals(NetMessage.MES_CHAT)) {
				String userName = userNames.get("Server");
				userName = (userName == null) ? "Server" : userName;
				netMes.messageContent = userName + ":" + netMes.messageContent;
			}
			sendMessage(netMes, "Server");
		}

	}

	/**
	 * 服务器向除了senderNetName外的所有客户端发送消息
	 * @param netMes 发送的消息
	 * @param senderNetName 需要排除的客户端的网络名称
	 */
	public void sendMessage(NetMessage netMes, String senderNetName) {
		if (senderNetName != null && !userNames.containsKey(senderNetName)) {
			if (Application.DEBUG > 3)
				System.out.println("非法的发送请求:一个没有注册的客户端请求发送");
			return;
		}

		Iterator<ServerSend> iter = clients.values().iterator();
		while (iter.hasNext()) {
			ServerSend serverSend = iter.next();
			if (serverSend != null && serverSend.isShutDown == false
					&& !serverSend.netName.equals(senderNetName)) {
				serverSend.sendMessage(netMes);
			}
		}
	}

	@Override
	public void run() {
		Socket socket;
		ServerSend serverSend;
		ServerReceive serverReceive;
		while (!shouldShutdown) {
			try {
				serverSocket.setSoTimeout(100);
				socket = serverSocket.accept();
				serverReceive = new ServerReceive(this, socket, "Client"
						+ clientNum);
				serverReceive.start();

				serverSend = new ServerSend(this, socket, "Client" + clientNum);
				userNames.put("Client" + clientNum, "Client" + clientNum);
				clients.put("Client" + clientNum, serverSend);
				++clientNum;
				// serverSends.add(serverSend);
				serverSend.start();
			} catch (SocketTimeoutException e) {
				// 无关紧要
			} catch (IOException e) {
				if (Application.DEBUG > 0)
					e.printStackTrace();
			}
		}
		try {
			serverSocket.close();
		} catch (IOException e) {
			if (Application.DEBUG > 0)
				e.printStackTrace();
		}
	}
}

⌨️ 快捷键说明

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