📄 paintserver.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 + -