import java.net.*;
//import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
//import java.util.Map;
import java.io.*;
public class Server {
List allClients =
new LinkedList();
ServerSocket server = null;
boolean started = false;
ClientListenner cl = null;
//客户端Control + C 时发生NullPointerException,在线程ClientServer处
public static void main(String[] args) {
new Server().start();
}
/*
* 服务器端构造函数
* 将监听接口绑定到本地端口8888处
*/
public Server(){
try {
server = new ServerSocket(8888);
} catch (BindException e) {
System.out.println( "端口使用中");
System.out.println( "请关掉相关程序并重新运行服务器!");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
}
/*
* 服务器启动函数
*/
public void start() {
System.out.println( "Server Starts!");
started = true;
cl = new ClientListenner(server);
cl.start();
readCommand();
}
/*
* 服务器关闭函数
*/
public void shutdown() {
started = false;
cl.close();
System.out.println( "server shutdown");
}
/*
* 读取控制台输入命令函数
*/
public void readCommand() {
BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
String str = null;
try{
while(started){
str = br.readLine();
excuteCommand(str);
}
} catch (NullPointerException e){/Control+C时发生的异常
System.out.println( "服务器中断");
} catch (IOException e) {
e.printStackTrace();
} finally {
try{
br.close();
} catch (IOException e1){
e1.printStackTrace();
}
}
}
/*
* 执行控制台命令函数
*/
public void excuteCommand(String command) {
if (command.toLowerCase().equals( "useramount")) {
System.out.println(getUserAmount());
} else if (command.toLowerCase().equals( "usernames")) {
System.out.println(getAllUserName());
} else if (command.toLowerCase().equals( "userinfo")) {
System.out.println(getUserInfo());
} else if (command.toLowerCase().equals( "help")) {
System.out.println(getHelp());
} else if (command.toLowerCase().equals( "shutdown")){
shutdown();
}
}
/*
* 获取当前服务器在线人数函数
*/
public String getUserAmount() {
return "当前在线用户人数为: " + allClients.size() + "\n";
}
/*
* 获取当前服务器在线用户的名字
*/
public String getAllUserName(){
StringBuffer sb = new StringBuffer();
sb.append( "当前在线用户是:");
sb.append( "\n");
for ( int i = 0; i < allClients.size(); i++) {
sb.append(allClients.get(i).userName);
}
return sb.toString();
}
/*
* 获取当前服务器在线用户的信息
* 包括用户个数和用户姓名
*/
public String getUserInfo() {
StringBuffer sb = new StringBuffer();
sb.append(getUserAmount());
sb.append(getAllUserName());
return sb.toString();
}
/*
* 提供服务器命令信息
*/
public String getHelp() {
StringBuffer sb = new StringBuffer();
sb.append( "useramount 显示当前在线用户人数\n");
sb.append( "usernames 显示当前在线用户的名字\n");
sb.append( "userinfo 显示当前在线用户的人数及姓名");
return sb.toString();
}
/*
* 监听客户端连接线程
* 为每一个新连接的客户端提供一个服务器线程
*/
class ClientListenner extends Thread {
ServerSocket s = null;
public ClientListenner(ServerSocket s) {
this.s = s;
}
@Override
public void run() {
try{
while (started) {
Socket c_server = s.accept();
ClientServer cs = new ClientServer(c_server);
allClients.add(cs);
System.out.println(cs.userName + "登录");
new Thread(cs).start();
}
} catch (SocketException e){
System.out.print("");//客户端关闭的时候发生异常
} catch (IOException e){
e.printStackTrace();
}
}
public void close() {
try {
started = false;
if (s != null)
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
* 服务器服务线程类
* 接受客户端的输入,并将获得到信息发送到所有的客户端
*/
class ClientServer implements Runnable {
Socket c_server = null;
ClientServer cs = null;
boolean connected = false;
DataOutputStream dout = null;
DataInputStream din = null;
String userName = null;
/*
* 构造函数
* 初始化从客户端获得的socket、建立服务器与客户端的连接、初始化输入输出流
*/
public ClientServer(Socket s) {
c_server = s;
connected = true;
try {
din = new DataInputStream(s.getInputStream());
dout = new DataOutputStream(s.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
register(receiveMessage());
}
/*
* 消息发送函数
* 向客户端发送消息
*/
public void sendMessage(String message) {
try {
dout.writeUTF(message);
dout.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
/*
* 消息接受函数
* 从客户端接受消息
*/
public String receiveMessage() {
String message = null;
try{
message = din.readUTF();
} catch (EOFException e){
System.out.println( "客户端中断!");
} catch (SocketException e){
System.out.print("");//客户端关闭的时候发生异常
} catch (IOException e){
e.printStackTrace();
}
return message;
}
@Override
public void run() {
String str = null;
sendMessage( "server says:hello,I am the server!");
while (connected) {
str = receiveMessage();
interpret(str);
}
close();
}
/*
* 服务线程类关闭函数
* 关闭相关输入输出流、socket
*/
public void close() {
try {
if (dout != null)
dout.close();
if (din != null)
din.close();
if (c_server != null)
c_server.close();
if (allClients.contains( this))
allClients.remove( this);
} catch (IOException e) {
e.printStackTrace();
}
}
/*
* 消息解释函数
* 根据消息类型选择执行相关操作
*/
public void interpret(String str) {
boolean bToAll = true;
switch (strType(str)) {
case 0:
sendToClient(bToAll, str);
break;
case 1:
bToAll = changePeople(str);
break;
case 2:
excuteUserCommand(str);
break;
default:
break;
}
}
/*
* 注册函数
* 服务器段记录登录用户名
*/
private void register(String name){
userName = name;
}
/*
* 命令执行函数
* 根据客户端发送过来的指令执行相关操作
*/
private void excuteUserCommand(String str){
String command = str.substring(1);
if (command.equals( "userinfo")){
sendMessage(getUserInfo());
}
else if(command.equals( "help")){
sendMessage(getHelp());
}
else if(command.equals( "bye")){
connected = false;
System.out.println(userName + "退出了");
allClients.remove( this);
}
}
/*
* 消息转发对象转换函数
* 选择单对单发送消息,或者群发消息
*/
private boolean changePeople(String str) {
String name = str.substring(1);
if (name.equals( "all")) {
return true;
} else {
for ( int i = 0; i < allClients.size(); i++) {
if (name.equals(allClients.get(i).userName)) {
cs = allClients.get(i);
return false;
}
}
}
return true;
}
/*
* 消息解释函数
* 根据消息起始字符调用返回整型值
* @return 1 表示对象转换
* @return 2 表示获取服务器信息
* @return 0 表示正常消息发送语句
*/
private int strType(String str){
if (str.startsWith( "-"))
return 1;
else if(str.startsWith( "?"))
return 2;
else
return 0;
}
/*
* 消息发送函数
* 根据传入的参数,将消息传给群发或者发送给指定客户端
*/
private void sendToClient( boolean bToAll,String str) {
if (bToAll) {
for ( int i = 0; i < allClients.size(); i++) {
allClients.get(i).sendMessage( this.userName + " says: " + str);
}
} else {
cs.sendMessage(cs.userName + " says: " + str);
}
}
}
}
//import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
//import java.util.Map;
import java.io.*;
public class Server {
List
ServerSocket server = null;
boolean started = false;
ClientListenner cl = null;
//客户端Control + C 时发生NullPointerException,在线程ClientServer处
public static void main(String[] args) {
new Server().start();
}
/*
* 服务器端构造函数
* 将监听接口绑定到本地端口8888处
*/
public Server(){
try {
server = new ServerSocket(8888);
} catch (BindException e) {
System.out.println( "端口使用中");
System.out.println( "请关掉相关程序并重新运行服务器!");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
}
/*
* 服务器启动函数
*/
public void start() {
System.out.println( "Server Starts!");
started = true;
cl = new ClientListenner(server);
cl.start();
readCommand();
}
/*
* 服务器关闭函数
*/
public void shutdown() {
started = false;
cl.close();
System.out.println( "server shutdown");
}
/*
* 读取控制台输入命令函数
*/
public void readCommand() {
BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
String str = null;
try{
while(started){
str = br.readLine();
excuteCommand(str);
}
} catch (NullPointerException e){/Control+C时发生的异常
System.out.println( "服务器中断");
} catch (IOException e) {
e.printStackTrace();
} finally {
try{
br.close();
} catch (IOException e1){
e1.printStackTrace();
}
}
}
/*
* 执行控制台命令函数
*/
public void excuteCommand(String command) {
if (command.toLowerCase().equals( "useramount")) {
System.out.println(getUserAmount());
} else if (command.toLowerCase().equals( "usernames")) {
System.out.println(getAllUserName());
} else if (command.toLowerCase().equals( "userinfo")) {
System.out.println(getUserInfo());
} else if (command.toLowerCase().equals( "help")) {
System.out.println(getHelp());
} else if (command.toLowerCase().equals( "shutdown")){
shutdown();
}
}
/*
* 获取当前服务器在线人数函数
*/
public String getUserAmount() {
return "当前在线用户人数为: " + allClients.size() + "\n";
}
/*
* 获取当前服务器在线用户的名字
*/
public String getAllUserName(){
StringBuffer sb = new StringBuffer();
sb.append( "当前在线用户是:");
sb.append( "\n");
for ( int i = 0; i < allClients.size(); i++) {
sb.append(allClients.get(i).userName);
}
return sb.toString();
}
/*
* 获取当前服务器在线用户的信息
* 包括用户个数和用户姓名
*/
public String getUserInfo() {
StringBuffer sb = new StringBuffer();
sb.append(getUserAmount());
sb.append(getAllUserName());
return sb.toString();
}
/*
* 提供服务器命令信息
*/
public String getHelp() {
StringBuffer sb = new StringBuffer();
sb.append( "useramount 显示当前在线用户人数\n");
sb.append( "usernames 显示当前在线用户的名字\n");
sb.append( "userinfo 显示当前在线用户的人数及姓名");
return sb.toString();
}
/*
* 监听客户端连接线程
* 为每一个新连接的客户端提供一个服务器线程
*/
class ClientListenner extends Thread {
ServerSocket s = null;
public ClientListenner(ServerSocket s) {
this.s = s;
}
@Override
public void run() {
try{
while (started) {
Socket c_server = s.accept();
ClientServer cs = new ClientServer(c_server);
allClients.add(cs);
System.out.println(cs.userName + "登录");
new Thread(cs).start();
}
} catch (SocketException e){
System.out.print("");//客户端关闭的时候发生异常
} catch (IOException e){
e.printStackTrace();
}
}
public void close() {
try {
started = false;
if (s != null)
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
* 服务器服务线程类
* 接受客户端的输入,并将获得到信息发送到所有的客户端
*/
class ClientServer implements Runnable {
Socket c_server = null;
ClientServer cs = null;
boolean connected = false;
DataOutputStream dout = null;
DataInputStream din = null;
String userName = null;
/*
* 构造函数
* 初始化从客户端获得的socket、建立服务器与客户端的连接、初始化输入输出流
*/
public ClientServer(Socket s) {
c_server = s;
connected = true;
try {
din = new DataInputStream(s.getInputStream());
dout = new DataOutputStream(s.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
register(receiveMessage());
}
/*
* 消息发送函数
* 向客户端发送消息
*/
public void sendMessage(String message) {
try {
dout.writeUTF(message);
dout.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
/*
* 消息接受函数
* 从客户端接受消息
*/
public String receiveMessage() {
String message = null;
try{
message = din.readUTF();
} catch (EOFException e){
System.out.println( "客户端中断!");
} catch (SocketException e){
System.out.print("");//客户端关闭的时候发生异常
} catch (IOException e){
e.printStackTrace();
}
return message;
}
@Override
public void run() {
String str = null;
sendMessage( "server says:hello,I am the server!");
while (connected) {
str = receiveMessage();
interpret(str);
}
close();
}
/*
* 服务线程类关闭函数
* 关闭相关输入输出流、socket
*/
public void close() {
try {
if (dout != null)
dout.close();
if (din != null)
din.close();
if (c_server != null)
c_server.close();
if (allClients.contains( this))
allClients.remove( this);
} catch (IOException e) {
e.printStackTrace();
}
}
/*
* 消息解释函数
* 根据消息类型选择执行相关操作
*/
public void interpret(String str) {
boolean bToAll = true;
switch (strType(str)) {
case 0:
sendToClient(bToAll, str);
break;
case 1:
bToAll = changePeople(str);
break;
case 2:
excuteUserCommand(str);
break;
default:
break;
}
}
/*
* 注册函数
* 服务器段记录登录用户名
*/
private void register(String name){
userName = name;
}
/*
* 命令执行函数
* 根据客户端发送过来的指令执行相关操作
*/
private void excuteUserCommand(String str){
String command = str.substring(1);
if (command.equals( "userinfo")){
sendMessage(getUserInfo());
}
else if(command.equals( "help")){
sendMessage(getHelp());
}
else if(command.equals( "bye")){
connected = false;
System.out.println(userName + "退出了");
allClients.remove( this);
}
}
/*
* 消息转发对象转换函数
* 选择单对单发送消息,或者群发消息
*/
private boolean changePeople(String str) {
String name = str.substring(1);
if (name.equals( "all")) {
return true;
} else {
for ( int i = 0; i < allClients.size(); i++) {
if (name.equals(allClients.get(i).userName)) {
cs = allClients.get(i);
return false;
}
}
}
return true;
}
/*
* 消息解释函数
* 根据消息起始字符调用返回整型值
* @return 1 表示对象转换
* @return 2 表示获取服务器信息
* @return 0 表示正常消息发送语句
*/
private int strType(String str){
if (str.startsWith( "-"))
return 1;
else if(str.startsWith( "?"))
return 2;
else
return 0;
}
/*
* 消息发送函数
* 根据传入的参数,将消息传给群发或者发送给指定客户端
*/
private void sendToClient( boolean bToAll,String str) {
if (bToAll) {
for ( int i = 0; i < allClients.size(); i++) {
allClients.get(i).sendMessage( this.userName + " says: " + str);
}
} else {
cs.sendMessage(cs.userName + " says: " + str);
}
}
}
}