diff --git a/.gitignore b/.gitignore
index 6eb1d58c9f9214657b561dccf2b4ba81373d613f..55aa0f5811a3116c330ceecf3df82d9555cb5558 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
/.idea/
/target/
/ArchiLab-tutorials.iml
+/base-tutorial/target/
diff --git a/base-tutorial/base-tutorial.iml b/base-tutorial/base-tutorial.iml
index 43feb3614bf5430fb0785b11e5b5a75ebd36ac9b..9215c225b1d96b3fe89b2267ce95a1364d6ccda9 100644
--- a/base-tutorial/base-tutorial.iml
+++ b/base-tutorial/base-tutorial.iml
@@ -14,7 +14,11 @@
+
+
+
+
diff --git a/base-tutorial/base.iml b/base-tutorial/base.iml
deleted file mode 100644
index 4e717d8d19cbb0c40409a9331863b61179053ff0..0000000000000000000000000000000000000000
--- a/base-tutorial/base.iml
+++ /dev/null
@@ -1,311 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/base-tutorial/pom.xml b/base-tutorial/pom.xml
index 358c1945513d6b0703ce928970077cb48b599094..858d966ca7011bfc9cc16c22a267e4fcd614918d 100644
--- a/base-tutorial/pom.xml
+++ b/base-tutorial/pom.xml
@@ -9,7 +9,7 @@
4.0.0
- base
+ base-tutorial
8
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/qqclientservice/ClientConnectServerThread.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/qqclientservice/ClientConnectServerThread.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed8d8f3bb2d17f08bbc8a53a3aef23b37c02750a
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/qqclientservice/ClientConnectServerThread.java
@@ -0,0 +1,65 @@
+package org.sikongsphere.qqnetwork.qqclient.qqclientservice;
+
+
+import org.sikongsphere.qqnetwork.qqcommon.Message;
+import org.sikongsphere.qqnetwork.qqcommon.MessageType;
+
+import java.io.*;
+import java.net.Socket;
+
+/**
+ * @author 徐艺阁
+ * @version 1.0
+ * 该类用于客户端接收从服务端发来的消息并做相应的处理
+ */
+public class ClientConnectServerThread extends Thread {
+ private Socket socket = new Socket();
+
+ public ClientConnectServerThread(Socket socket) {
+ this.socket = socket;
+ }
+
+ public Socket getSocket() {
+ return socket;
+ }
+
+ public void setSocket(Socket socket) {
+ this.socket = socket;
+ }
+
+ @Override
+ public void run() {
+ while (true) {
+ try {
+ System.out.println("客户端线程,等待读取从服务器端发送的消息");
+ ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
+ Message message = (Message) ois.readObject();
+ //判断这个message类型,然后做相应的业务处理
+ if (message.getMesType().equals(MessageType.MESSAGE_RET_ONLINE_FRIEND)) {//获取在线用户列表
+ String[] onlineUsers = message.getSendCotent().split(" ");
+ System.out.println("\n" + "=========当前在线用户列表=========");
+ for (int i = 0; i < onlineUsers.length; i++) {
+ System.out.println("用户:" + onlineUsers[i]);
+ }
+ } else if (message.getMesType().equals(MessageType.MESSAGE_COMM_MES)) {//私聊消息
+ System.out.println("\n收到" + message.getSender() + "发给" + message.getGetter() + "的消息");
+ System.out.println(message.getSendCotent());
+ } else if (message.getMesType().equals(MessageType.MESSAGE_TO_ALL_MES)) {//群发消息
+ System.out.println("\n收到" + message.getSender() + "发给大家的消息");
+ System.out.println(message.getSendCotent());
+ } else if (message.getMesType().equals(MessageType.MESSAGE_FILE_MES)) {//发文件
+ System.out.println("\n收到" + message.getSender() + "发给" + message.getGetter() +
+ "的文件:" + message.getSrc() + "到我的电脑目录:" + message.getDest());
+ byte[] bytes = message.getFileBytes();
+ BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(message.getDest()));
+ bos.write(bytes);
+ bos.close();
+ System.out.println("文件保存在" + message.getDest() + "成功");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+ }
+}
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/qqclientservice/FileClientService.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/qqclientservice/FileClientService.java
new file mode 100644
index 0000000000000000000000000000000000000000..54e57969bcf4424337a292f8c7f247bcf5d71e8f
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/qqclientservice/FileClientService.java
@@ -0,0 +1,45 @@
+package org.sikongsphere.qqnetwork.qqclient.qqclientservice;
+
+import org.sikongsphere.qqnetwork.qqclient.view.Utility;
+import org.sikongsphere.qqnetwork.qqcommon.Message;
+import org.sikongsphere.qqnetwork.qqcommon.MessageType;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Date;
+
+/**
+ * @author 徐艺阁
+ * @version 1.0
+ * 该类用于发送文件
+ */
+public class FileClientService {
+ public void sendFile(String sender) {
+ try {
+ System.out.println("请输入你想发送文件的对象名:");
+ String getter = Utility.readString(50);
+ System.out.println("请输入发送文件的完整路径:");
+ String src = Utility.readString(100);
+ System.out.println("请输入发送文件到对方的完整路径:");
+ String dest = Utility.readString(100);
+ BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
+ byte[] contentBytes = StreamUtils.streamToByteArray(bis);
+ Message message = new Message();
+ message.setMesType(MessageType.MESSAGE_FILE_MES);
+ message.setFileBytes(contentBytes);
+ message.setSender(sender);
+ message.setGetter(getter);
+ message.setDest(dest);
+ message.setSrc(src);
+ message.setSendTime(new Date().toString());
+ System.out.println("\n" + sender + "给" + getter + "发送文件:" + src + "到对方电脑目录" + dest);
+ ObjectOutputStream oos = new ObjectOutputStream(ManageClientConnectServerThread.
+ getClientConnectServerThread(sender).getSocket().getOutputStream());
+ oos.writeObject(message);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+}
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/qqclientservice/ManageClientConnectServerThread.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/qqclientservice/ManageClientConnectServerThread.java
new file mode 100644
index 0000000000000000000000000000000000000000..062b7e212fe47dd40f9105ee3b2635d05a3ae8c4
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/qqclientservice/ManageClientConnectServerThread.java
@@ -0,0 +1,19 @@
+package org.sikongsphere.qqnetwork.qqclient.qqclientservice;
+
+import java.util.HashMap;
+
+/**
+ * @author 徐艺阁
+ * @version 1.0
+ * 该类用于管理用户端联系到服务端的线程
+ */
+public class ManageClientConnectServerThread {
+ private static HashMap hashMap = new HashMap<>();
+
+ public static void addClientConnectServerThread(String userID, ClientConnectServerThread clientConnectServerThread) {
+ hashMap.put(userID,clientConnectServerThread);
+ }
+ public static ClientConnectServerThread getClientConnectServerThread(String userID){
+ return hashMap.get(userID);
+ }
+}
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/qqclientservice/StreamUtils.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/qqclientservice/StreamUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..738c23e95d308d3e94def34f182b8f6ecc5fb9d0
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/qqclientservice/StreamUtils.java
@@ -0,0 +1,49 @@
+package org.sikongsphere.qqnetwork.qqclient.qqclientservice;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+/**
+ * 此类用于演示关于流的读写方法
+ *
+ */
+public class StreamUtils {
+ /**
+ * 功能:将输入流转换成byte[], 即可以把文件的内容读入到byte[]
+ * @param is
+ * @return
+ * @throws Exception
+ */
+ public static byte[] streamToByteArray(InputStream is) throws Exception{
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建输出流对象
+ byte[] b = new byte[1024];//字节数组
+ int len;
+ while((len=is.read(b))!=-1){//循环读取
+ bos.write(b, 0, len);//把读取到的数据,写入bos
+ }
+ byte[] array = bos.toByteArray();//然后将bos 转成字节数组
+ bos.close();
+ return array;
+ }
+ /**
+ * 功能:将InputStream转换成String
+ * @param is
+ * @return
+ * @throws Exception
+ */
+
+ public static String streamToString(InputStream is) throws Exception{
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ StringBuilder builder= new StringBuilder();
+ String line;
+ while((line=reader.readLine())!=null){
+ builder.append(line+"\r\n");
+ }
+ return builder.toString();
+
+ }
+
+}
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/qqclientservice/UserClientService.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/qqclientservice/UserClientService.java
new file mode 100644
index 0000000000000000000000000000000000000000..a117ff0bc9e6855df937be1c0169a9d6e6640780
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/qqclientservice/UserClientService.java
@@ -0,0 +1,123 @@
+package org.sikongsphere.qqnetwork.qqclient.qqclientservice;
+
+import org.sikongsphere.qqnetwork.qqclient.view.Utility;
+import org.sikongsphere.qqnetwork.qqcommon.Message;
+import org.sikongsphere.qqnetwork.qqcommon.MessageType;
+import org.sikongsphere.qqnetwork.qqcommon.User;
+
+import java.io.*;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.Date;
+
+/**
+ * @author 徐艺阁
+ * @version 1.0
+ * 该类完成用户登录,发送消息,获得在线用户列表,用户退出等功能
+ */
+public class UserClientService {
+ private User user = new User();
+ Socket socket = new Socket();
+
+ //验证用户ID和密码是否匹配
+ public boolean checkUser(String userID, String userKey) {
+ boolean b = false;
+ user.setUserId(userID);
+ user.setUserKey(userKey);
+ try {
+ socket = new Socket(InetAddress.getByName("127.0.0.1"), 9999);
+ ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
+ //将用户信息发给服务端
+ oos.writeObject(user);
+ ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
+ //从服务端收到消息
+ Message message = (Message) ois.readObject();
+ if (message.getMesType().equals(MessageType.MESSAGE_LOGIN_SUCCEED)) {
+ //用户登录成功,启动该用户与服务端之间的线程
+ ClientConnectServerThread clientConnectServerThread = new ClientConnectServerThread(socket);
+ clientConnectServerThread.start();
+ //将该线程加入线程集合
+ ManageClientConnectServerThread.addClientConnectServerThread(userID, clientConnectServerThread);
+ b = true;
+ } else {
+ //用户登录失败
+ socket.close();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return b;
+ }
+
+ // 获得在线用户列表
+ public void onlineFriendList() {
+ Message message = new Message();
+ message.setMesType(MessageType.MESSAGE_GET_ONLINE_FRIEND);
+ message.setSender(user.getUserId());
+ try {
+ ObjectOutputStream oos = new ObjectOutputStream(ManageClientConnectServerThread.
+ getClientConnectServerThread(user.getUserId()).getSocket().getOutputStream());
+ oos.writeObject(message);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ //退出系统
+ public void exit() {
+ Message message = new Message();
+ message.setMesType(MessageType.MESSAGE_CLIENT_EXIT);
+ message.setSender(user.getUserId());
+ try {
+ ObjectOutputStream oos = new ObjectOutputStream(ManageClientConnectServerThread.
+ getClientConnectServerThread(user.getUserId()).getSocket().getOutputStream());
+ oos.writeObject(message);
+ System.out.println(user.getUserId() + "退出系统");
+ System.exit(0);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ //私发消息
+ public void sendMessageToOne() {
+ System.out.println("请输入您要私聊的对象:");
+ String getter = Utility.readString(50);
+ System.out.println("请输入您要私聊的内容:");
+ String sendCotent = Utility.readString(100);
+ Message message = new Message();
+ message.setMesType(MessageType.MESSAGE_COMM_MES);
+ message.setSender(user.getUserId());
+ message.setGetter(getter);
+ message.setSendCotent(sendCotent);
+ message.setSendTime(new Date().toString());
+ try {
+ System.out.println(user.getUserId() + "给" + getter + "私发消息");
+ ObjectOutputStream oos = new ObjectOutputStream(ManageClientConnectServerThread.
+ getClientConnectServerThread(user.getUserId()).getSocket().getOutputStream());
+ oos.writeObject(message);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ //群发消息
+ public void sendMessageToAll() {
+ System.out.println("请输入你要群发的消息内容:");
+ String sendCotent = Utility.readString(100);
+ Message message = new Message();
+ message.setMesType(MessageType.MESSAGE_TO_ALL_MES);
+ message.setSender(user.getUserId());
+ message.setSendCotent(sendCotent);
+ message.setSendTime(new Date().toString());
+ try {
+ ObjectOutputStream oos = new ObjectOutputStream(ManageClientConnectServerThread.
+ getClientConnectServerThread(user.getUserId()).getSocket().getOutputStream());
+ oos.writeObject(message);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
+
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/view/Utility.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/view/Utility.java
new file mode 100644
index 0000000000000000000000000000000000000000..d9e51afa3e0e65d30bcd67e05f59b81d1bf7d46f
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/view/Utility.java
@@ -0,0 +1,168 @@
+package org.sikongsphere.qqnetwork.qqclient.view;
+
+import java.util.Scanner;
+
+public class Utility {
+ private static Scanner scanner = new Scanner(System.in);
+
+
+ /**
+ * 功能:读取键盘输入的一个菜单选项,值:1——5的范围
+ * @return 1——5
+ */
+ public static char readMenuSelection() {
+ char c;
+ for (; ; ) {
+ String str = readKeyBoard(1, false);//包含一个字符的字符串
+ c = str.charAt(0);//将字符串转换成字符char类型
+ if (c != '1' && c != '2' &&
+ c != '3' && c != '4' && c != '5') {
+ System.out.print("选择错误,请重新输入:");
+ } else break;
+ }
+ return c;
+ }
+
+ /**
+ * 功能:读取键盘输入的一个字符
+ * @return 一个字符
+ */
+ public static char readChar() {
+ String str = readKeyBoard(1, false);//就是一个字符
+ return str.charAt(0);
+ }
+ /**
+ * 功能:读取键盘输入的一个字符,如果直接按回车,则返回指定的默认值;否则返回输入的那个字符
+ * @param defaultValue 指定的默认值
+ * @return 默认值或输入的字符
+ */
+
+ public static char readChar(char defaultValue) {
+ String str = readKeyBoard(1, true);//要么是空字符串,要么是一个字符
+ return (str.length() == 0) ? defaultValue : str.charAt(0);
+ }
+
+ /**
+ * 功能:读取键盘输入的整型,长度小于2位
+ * @return 整数
+ */
+ public static int readInt() {
+ int n;
+ for (; ; ) {
+ String str = readKeyBoard(10, false);//一个整数,长度<=2位
+ try {
+ n = Integer.parseInt(str);//将字符串转换成整数
+ break;
+ } catch (NumberFormatException e) {
+ System.out.print("数字输入错误,请重新输入:");
+ }
+ }
+ return n;
+ }
+ /**
+ * 功能:读取键盘输入的 整数或默认值,如果直接回车,则返回默认值,否则返回输入的整数
+ * @param defaultValue 指定的默认值
+ * @return 整数或默认值
+ */
+ public static int readInt(int defaultValue) {
+ int n;
+ for (; ; ) {
+ String str = readKeyBoard(10, true);
+ if (str.equals("")) {
+ return defaultValue;
+ }
+
+ //异常处理...
+ try {
+ n = Integer.parseInt(str);
+ break;
+ } catch (NumberFormatException e) {
+ System.out.print("数字输入错误,请重新输入:");
+ }
+ }
+ return n;
+ }
+
+ /**
+ * 功能:读取键盘输入的指定长度的字符串
+ * @param limit 限制的长度
+ * @return 指定长度的字符串
+ */
+
+ public static String readString(int limit) {
+ return readKeyBoard(limit, false);
+ }
+
+ /**
+ * 功能:读取键盘输入的指定长度的字符串或默认值,如果直接回车,返回默认值,否则返回字符串
+ * @param limit 限制的长度
+ * @param defaultValue 指定的默认值
+ * @return 指定长度的字符串
+ */
+
+ public static String readString(int limit, String defaultValue) {
+ String str = readKeyBoard(limit, true);
+ return str.equals("")? defaultValue : str;
+ }
+
+
+ /**
+ * 功能:读取键盘输入的确认选项,Y或N
+ * 将小的功能,封装到一个方法中.
+ * @return Y或N
+ */
+ public static char readConfirmSelection() {
+ System.out.println("请输入你的选择(Y/N)");
+ char c;
+ for (; ; ) {//无限循环
+ //在这里,将接受到字符,转成了大写字母
+ //y => Y n=>N
+ String str = readKeyBoard(1, false).toUpperCase();
+ c = str.charAt(0);
+ if (c == 'Y' || c == 'N') {
+ break;
+ } else {
+ System.out.print("选择错误,请重新输入:");
+ }
+ }
+ return c;
+ }
+
+ /**
+ * 功能: 读取一个字符串
+ * @param limit 读取的长度
+ * @param blankReturn 如果为true ,表示 可以读空字符串。
+ * 如果为false表示 不能读空字符串。
+ *
+ * 如果输入为空,或者输入大于limit的长度,就会提示重新输入。
+ * @return
+ */
+ private static String readKeyBoard(int limit, boolean blankReturn) {
+
+ //定义了字符串
+ String line = "";
+
+ //scanner.hasNextLine() 判断有没有下一行
+ while (scanner.hasNextLine()) {
+ line = scanner.nextLine();//读取这一行
+
+ //如果line.length=0, 即用户没有输入任何内容,直接回车
+ if (line.length() == 0) {
+ if (blankReturn) return line;//如果blankReturn=true,可以返回空串
+ else continue; //如果blankReturn=false,不接受空串,必须输入内容
+ }
+
+ //如果用户输入的内容大于了 limit,就提示重写输入
+ //如果用户如的内容 >0 <= limit ,我就接受
+ if (line.length() < 1 || line.length() > limit) {
+ System.out.print("输入长度(不能大于" + limit + ")错误,请重新输入:");
+ continue;
+ }
+ break;
+ }
+
+ return line;
+ }
+}
+
+
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/view/View.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/view/View.java
new file mode 100644
index 0000000000000000000000000000000000000000..c1719899f6ceb203ff882d446c5af4ae49bd1197
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqclient/view/View.java
@@ -0,0 +1,77 @@
+package org.sikongsphere.qqnetwork.qqclient.view;
+
+import org.sikongsphere.qqnetwork.qqclient.qqclientservice.FileClientService;
+import org.sikongsphere.qqnetwork.qqclient.qqclientservice.UserClientService;
+
+/**
+ * @author 徐艺阁
+ * @version 1.0
+ * 客户端的菜单界面
+ */
+
+
+public class View {
+ public void showView() {
+ new View().mainMenu();
+ }
+
+ private boolean loop = true;//控制是否产生菜单
+ private String key = "";
+ private UserClientService userClientService = new UserClientService();
+ private FileClientService fileClientService = new FileClientService();
+
+ private void mainMenu() {
+ while (loop) {
+ System.out.println("===========欢迎登录网络通信系统===========");
+ System.out.println("\t\t 1 登录系统");
+ System.out.println("\t\t 9 退出系统");
+ System.out.print("请输入你的选择: ");
+ key = Utility.readString(1);
+ switch (key) {
+ case ("1"):
+ System.out.print("请输入用户号: ");
+ String userId = Utility.readString(50);
+ System.out.print("请输入密 码: ");
+ String userKey = Utility.readString(50);
+ if (userClientService.checkUser(userId, userKey)) { //验证用户ID和密码是否匹配
+ while (loop) {
+ System.out.println("\n=========网络通信系统二级菜单(用户 " + userId + " )=======");
+ System.out.println("\t\t 1 显示在线用户列表");
+ System.out.println("\t\t 2 群发消息");
+ System.out.println("\t\t 3 私聊消息");
+ System.out.println("\t\t 4 发送文件");
+ System.out.println("\t\t 9 退出系统");
+ System.out.print("请输入你的选择: ");
+ key = Utility.readString(1);
+ switch (key) {
+ case ("1")://在线用户列表
+ userClientService.onlineFriendList();
+ break;
+ case ("2")://群发消息
+ userClientService.sendMessageToAll();
+ break;
+ case ("3")://私信
+ userClientService.sendMessageToOne();
+ break;
+ case ("4")://发文件
+ fileClientService.sendFile(userId);
+ break;
+ case ("9")://退出系统
+ userClientService.exit();
+ loop = false;
+ break;
+ }
+ }
+ } else {
+ System.out.println("=========登录失败=========");
+ }
+ break;
+ case ("9"):
+ System.out.println("退出系统");
+ loop = false;
+ break;
+ }
+ }
+
+ }
+}
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqcommon/Message.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqcommon/Message.java
new file mode 100644
index 0000000000000000000000000000000000000000..bab78c8c4175672da11994e4a18711ec89f2deea
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqcommon/Message.java
@@ -0,0 +1,93 @@
+package org.sikongsphere.qqnetwork.qqcommon;
+
+import java.io.Serializable;
+
+/**
+ * @author 徐艺阁
+ * @version 1.0
+ */
+public class Message implements Serializable {
+ private static final long serialVersionUID = 1L;
+ private String sender;
+ private String getter;
+ private String sendTime;
+ private String sendCotent;
+ private String mesType;
+// 进行拓展和文件相关的成员
+ private byte[] fileBytes;
+ private String dest;
+ private String src;
+ private int fileLen;
+
+ public byte[] getFileBytes() {
+ return fileBytes;
+ }
+
+ public void setFileBytes(byte[] fileBytes) {
+ this.fileBytes = fileBytes;
+ }
+
+ public String getDest() {
+ return dest;
+ }
+
+ public void setDest(String dest) {
+ this.dest = dest;
+ }
+
+ public String getSrc() {
+ return src;
+ }
+
+ public void setSrc(String src) {
+ this.src = src;
+ }
+
+ public int getFileLen() {
+ return fileLen;
+ }
+
+ public void setFileLen(int fileLen) {
+ this.fileLen = fileLen;
+ }
+
+ public String getMesType() {
+ return mesType;
+ }
+
+ public void setMesType(String mesType) {
+ this.mesType = mesType;
+ }
+
+ public String getSender() {
+ return sender;
+ }
+
+ public void setSender(String sender) {
+ this.sender = sender;
+ }
+
+ public String getGetter() {
+ return getter;
+ }
+
+ public void setGetter(String getter) {
+ this.getter = getter;
+ }
+
+ public String getSendTime() {
+ return sendTime;
+ }
+
+ public void setSendTime(String sendTime) {
+ this.sendTime = sendTime;
+ }
+
+ public String getSendCotent() {
+ return sendCotent;
+ }
+
+ public void setSendCotent(String sendCotent) {
+ this.sendCotent = sendCotent;
+ }
+}
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqcommon/MessageType.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqcommon/MessageType.java
new file mode 100644
index 0000000000000000000000000000000000000000..9ddfaf83509d3bcad6089816f9a0ff2f5f27b85f
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqcommon/MessageType.java
@@ -0,0 +1,16 @@
+package org.sikongsphere.qqnetwork.qqcommon;
+
+/**
+ * @author 徐艺阁
+ * @version 1.0
+ */
+public interface MessageType {
+ String MESSAGE_LOGIN_SUCCEED = "1"; //登录成功信息
+ String MESSAGE_LOGIN_FAIL = "2"; //登录失败信息
+ String MESSAGE_COMM_MES = "3"; //普通信息包
+ String MESSAGE_GET_ONLINE_FRIEND = "4"; //要求返回在线用户列表
+ String MESSAGE_RET_ONLINE_FRIEND = "5"; //返回在线用户列表
+ String MESSAGE_CLIENT_EXIT = "6"; //客户退出
+ String MESSAGE_TO_ALL_MES = "7"; //群发消息报
+ String MESSAGE_FILE_MES = "8"; //文件消息(发送文件)
+}
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqcommon/User.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqcommon/User.java
new file mode 100644
index 0000000000000000000000000000000000000000..235be9bac960f872a680f19992ef226b427ca3e6
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqcommon/User.java
@@ -0,0 +1,39 @@
+package org.sikongsphere.qqnetwork.qqcommon;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.net.Socket;
+
+/**
+ * @author 徐艺阁
+ * @version 1.0
+ */
+public class User implements Serializable {
+ private static final long serialVersionUID = 1L;
+ private String userId;
+ private String userKey;
+
+ public User() {
+ }
+
+ public User(String userId, String userKey) {
+ this.userId = userId;
+ this.userKey = userKey;
+ }
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public String getUserKey() {
+ return userKey;
+ }
+
+ public void setUserKey(String userKey) {
+ this.userKey = userKey;
+ }
+}
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/ManageClientThreads.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/ManageClientThreads.java
new file mode 100644
index 0000000000000000000000000000000000000000..86667ce122a248b5bf288b059e42f9f9c51ef8d5
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/ManageClientThreads.java
@@ -0,0 +1,38 @@
+package org.sikongsphere.qqnetwork.qqserver;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * @author 徐艺阁
+ * @version 1.0
+ * 该类用于管理服务端与客户端联系的线程
+ */
+public class ManageClientThreads {
+ private static HashMap hashMap= new HashMap<>();
+
+ public static HashMap getHashMap() {
+ return hashMap;
+ }
+
+ public static void setHashMap(HashMap hashMap) {
+ ManageClientThreads.hashMap = hashMap;
+ }
+ public static void removeServerConnectClientThread(String userId){
+ hashMap.remove(userId);
+ }
+ public static void addServerConnectClientThread(String userID, ServerConnectClientThread serverConnectClientThread){
+ hashMap.put(userID,serverConnectClientThread);
+ }
+ public static ServerConnectClientThread getServerConnectClientThread(String userID){
+ return hashMap.get(userID);
+ }
+ public static String getOnlineUser(){
+ Iterator iterator = hashMap.keySet().iterator();
+ String onlineUserList = "";
+ while (iterator.hasNext()) {
+ onlineUserList += iterator.next().toString() + " ";
+ }
+ return onlineUserList;
+ }
+}
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/ManageToOfflineUserMessage.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/ManageToOfflineUserMessage.java
new file mode 100644
index 0000000000000000000000000000000000000000..e8d116913aa937008926306b5f657fecdbaa3d2e
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/ManageToOfflineUserMessage.java
@@ -0,0 +1,40 @@
+package org.sikongsphere.qqnetwork.qqserver;
+
+import org.sikongsphere.qqnetwork.qqcommon.Message;
+
+import java.util.ArrayList;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author 徐艺阁
+ * @version 1.0
+ */
+public class ManageToOfflineUserMessage {
+ private static ConcurrentHashMap> hashMap = new ConcurrentHashMap<>();
+
+ public static ConcurrentHashMap> getHashMap() {
+ return hashMap;
+ }
+
+ public static void setHashMap(ConcurrentHashMap> hashMap) {
+ ManageToOfflineUserMessage.hashMap = hashMap;
+ }
+
+ public static void addToOfflineUserMessage(String getter, Message message) {
+ ArrayList messages = hashMap.get(getter);
+ if (messages == null) {
+ messages = new ArrayList<>();
+ messages.add(message);
+ hashMap.put(getter, messages);
+ } else {
+ messages.add(message);
+ hashMap.put(getter, messages);
+ }
+
+ }
+
+ public static void removeToOfflineUserMessage(String getter) {
+ hashMap.remove(getter);
+ }
+
+}
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/QQServer.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/QQServer.java
new file mode 100644
index 0000000000000000000000000000000000000000..bfd5f8b3f2e7267cc0c20794d2de653d6bbc6867
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/QQServer.java
@@ -0,0 +1,84 @@
+package org.sikongsphere.qqnetwork.qqserver;
+
+import org.sikongsphere.qqnetwork.qqcommon.Message;
+import org.sikongsphere.qqnetwork.qqcommon.MessageType;
+import org.sikongsphere.qqnetwork.qqcommon.User;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author 徐艺阁
+ * @version 1.0
+ * 该类用于服务端判断用户是否可以登录成功
+ */
+@SuppressWarnings({"all"})
+public class QQServer {
+ private ServerSocket ss = null;
+ private static ConcurrentHashMap validUsers = new ConcurrentHashMap<>();
+
+ static {
+ validUsers.put("100", new User("100", "123456"));
+ validUsers.put("200", new User("200", "123456"));
+ validUsers.put("300", new User("300", "123456"));
+ validUsers.put("至尊宝", new User("至尊宝", "123456"));
+ validUsers.put("紫霞仙子", new User("紫霞仙子", "123456"));
+ validUsers.put("菩提老祖", new User("菩提老祖", "123456"));
+ }
+//用于判断用户是否存在及用户账号,密码是否匹配
+ private boolean checkUser(String userID, String userKey) {
+ User user = validUsers.get(userID);
+ if (user == null) {
+ return false;
+ }
+ if (!(user.getUserKey().equals(userKey))) {
+ return false;
+ }
+ return true;
+ }
+
+ public QQServer() {
+ try {
+ System.out.println("服务端在9999端口监听...");
+ ss = new ServerSocket(9999);
+ //系统给客户端推送消息的线程
+ new Thread(new SendMessageToAllService()).start();
+ while (true) {
+ Socket socket = ss.accept();
+ ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
+ User user = (User) ois.readObject();
+ Message message = new Message();
+ ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
+ //判断从客户端接收到的消息类型,做相应的处理
+ if (checkUser(user.getUserId(), user.getUserKey())) {
+ message.setMesType(MessageType.MESSAGE_LOGIN_SUCCEED);
+ oos.writeObject(message);
+ //创建与该客户端连接的服务端线程
+ ServerConnectClientThread serverConnectClientThread =
+ new ServerConnectClientThread(socket, user.getUserId());
+ //与该客户端连接的服务端线程启动
+ serverConnectClientThread.start();
+ ManageClientThreads.addServerConnectClientThread(user.getUserId(), serverConnectClientThread);
+ } else {
+ //用户登陆失败
+ System.out.println("用户 id=" + user.getUserId() + " key=" + user.getUserKey() + " 验证失败");
+ message.setMesType(MessageType.MESSAGE_LOGIN_FAIL);
+ oos.writeObject(message);
+ socket.close();
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ ss.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/SendMessageToAllService.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/SendMessageToAllService.java
new file mode 100644
index 0000000000000000000000000000000000000000..f99a83338fe9194efa87df832418f4c7adcedb37
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/SendMessageToAllService.java
@@ -0,0 +1,48 @@
+package org.sikongsphere.qqnetwork.qqserver;
+
+import org.sikongsphere.qqnetwork.qqcommon.Message;
+import org.sikongsphere.qqnetwork.qqcommon.MessageType;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.util.Date;
+import java.util.Iterator;
+
+/**
+ * @author 徐艺阁
+ * @version 1.0
+ * 该类用于服务端推送消息
+ */
+public class SendMessageToAllService extends Thread{
+
+ @Override
+ public void run() {
+ while (true){
+ System.out.println("请输入服务器要推送的新闻/消息[输入exit表示退出推送服务线程]");
+ String news = Utility.readString(100);
+ if(news.equals("exit")){
+ System.out.println("退出服务器推送消息服务成功");
+ break;
+ }
+ Message message = new Message();
+ message.setSender("服务器");
+ message.setMesType(MessageType.MESSAGE_TO_ALL_MES);
+ message.setSendCotent(news);
+ message.setSendTime(new Date().toString());
+ System.out.println("服务器推送消息给所有人 说: " + news);
+ //遍历在线用户ID,创建相应ID的对象输出流
+ Iterator iterator = ManageClientThreads.getHashMap().keySet().iterator();
+ while (iterator.hasNext()) {
+ String key = iterator.next();
+ try {
+ ObjectOutputStream oos = new ObjectOutputStream(ManageClientThreads.
+ getServerConnectClientThread(key).getSocket().getOutputStream());
+ oos.writeObject(message);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ }
+}
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/ServerConnectClientThread.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/ServerConnectClientThread.java
new file mode 100644
index 0000000000000000000000000000000000000000..89ebe05c0c110d8b0162e74900efde0b6e77ef76
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/ServerConnectClientThread.java
@@ -0,0 +1,151 @@
+package org.sikongsphere.qqnetwork.qqserver;
+
+import org.sikongsphere.qqnetwork.qqcommon.Message;
+import org.sikongsphere.qqnetwork.qqcommon.MessageType;
+
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.Socket;
+import java.util.Iterator;
+
+/**
+ * @author 徐艺阁
+ * @version 1.0
+ * 该类的一个对象和某个客户端保持联系
+ */
+@SuppressWarnings({"all"})
+public class ServerConnectClientThread extends Thread {
+ private Socket socket = new Socket();
+ private String userId;
+
+ public ServerConnectClientThread(Socket socket, String userId) {
+ this.socket = socket;
+ this.userId = userId;
+ }
+
+ public Socket getSocket() {
+ return socket;
+ }
+
+ public void setSocket(Socket socket) {
+ this.socket = socket;
+ }
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public static boolean judgeUserState(String getter) {
+ String[] onlineUser = ManageClientThreads.getOnlineUser().split(" ");
+ for (int i = 0; i < onlineUser.length; i++) {
+ if (getter.equals(onlineUser[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void run() {
+ while (true) {
+ System.out.println("服务端和客户端" + userId + " 保持通信,读取数据...");
+ try {
+ ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
+ Message message = (Message) ois.readObject();
+ //判断从客户端收到的消息类型
+ if (message.getMesType().equals(MessageType.MESSAGE_GET_ONLINE_FRIEND)) {
+ System.out.println(message.getSender() + "要在线用户列表");//获取在线用户列表
+ String onlineUser = ManageClientThreads.getOnlineUser();
+ Message message2 = new Message();
+ message2.setMesType(MessageType.MESSAGE_RET_ONLINE_FRIEND);
+ message2.setGetter(message.getSender());
+ message2.setSendCotent(onlineUser);
+ ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
+ oos.writeObject(message2);
+ } else if (message.getMesType().equals(MessageType.MESSAGE_CLIENT_EXIT)) {//退出系统
+ System.out.println(message.getSender() + "退出");
+ socket.close();
+ ManageClientThreads.removeServerConnectClientThread(userId);
+ break;
+ } else if (message.getMesType().equals(MessageType.MESSAGE_COMM_MES)) {//私聊消息
+ if (judgeUserState(message.getGetter())) {//给在线用户私聊消息
+ System.out.println(message.getSender() + "发给在线用户" + message.getGetter() + "的消息");
+ ObjectOutputStream oos = new ObjectOutputStream(ManageClientThreads.
+ getServerConnectClientThread(message.getGetter()).getSocket().getOutputStream());
+ oos.writeObject(message);
+ } else {//给离线用户私聊消息
+ System.out.println(message.getSender() + "发给离线用户" + message.getGetter() + "的消息");
+ //用户不在线,将消息加到离线消息集合
+ ManageToOfflineUserMessage.addToOfflineUserMessage(message.getGetter(), message);
+ //线程判断用户是否上线
+ while (true) {
+ if (judgeUserState(message.getGetter())) {
+ try {
+ System.out.println(message.getGetter() + "上线了");
+ Iterator messages = ManageToOfflineUserMessage.getHashMap().get(message.getGetter()).iterator();
+ while (messages.hasNext()) {
+ Message arrayMessage = messages.next();
+ ObjectOutputStream oos = new ObjectOutputStream(ManageClientThreads.
+ getServerConnectClientThread(message.getGetter()).getSocket().getOutputStream());
+ oos.writeObject(arrayMessage);
+ }
+ //将上线用户的离线消息从集合中删除
+ ManageToOfflineUserMessage.removeToOfflineUserMessage(message.getGetter());
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ break;
+ }
+ }
+ }
+ }
+ } else if (message.getMesType().equals(MessageType.MESSAGE_TO_ALL_MES)) {//群发消息
+ String[] onlineUser = ManageClientThreads.getOnlineUser().split(" ");
+ for (int i = 0; i < onlineUser.length; i++) {
+ if (!(onlineUser[i].equals(message.getSender()))) {
+ message.setGetter(onlineUser[i]);
+ System.out.println(message.getSender() + "发给" + message.getGetter() + "的消息");
+ ObjectOutputStream oos = new ObjectOutputStream(ManageClientThreads.
+ getServerConnectClientThread(onlineUser[i]).getSocket().getOutputStream());
+ oos.writeObject(message);
+ }
+ }
+ } else if (message.getMesType().equals(MessageType.MESSAGE_FILE_MES)) {//发文件
+ //判断收件人是否在线
+ if (judgeUserState(message.getGetter())) {
+ System.out.println(message.getSender() + "发给" + message.getGetter() + "的文件");
+ ObjectOutputStream oos = new ObjectOutputStream(ManageClientThreads.
+ getServerConnectClientThread(message.getGetter()).getSocket().getOutputStream());
+ oos.writeObject(message);
+ }else {
+ System.out.println(message.getSender() + "发给离线用户" + message.getGetter() + "的文件");
+ ManageToOfflineUserMessage.addToOfflineUserMessage(message.getGetter(),message);
+ while (true){
+ //监视离线用户是否上线
+ if(judgeUserState(message.getGetter())){
+ System.out.println(message.getGetter() + "上线了");
+ Iterator messages = ManageToOfflineUserMessage.getHashMap().get(message.getGetter()).iterator();
+ while (messages.hasNext()) {
+ Message arrayMessage = messages.next();
+ ObjectOutputStream oos = new ObjectOutputStream(ManageClientThreads.
+ getServerConnectClientThread(message.getGetter()).getSocket().getOutputStream());
+ oos.writeObject(arrayMessage);
+ }
+ //将上线用户的离线文件从集合中删除
+ ManageToOfflineUserMessage.removeToOfflineUserMessage(message.getGetter());
+ break;
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+ }
+}
diff --git a/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/Utility.java b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/Utility.java
new file mode 100644
index 0000000000000000000000000000000000000000..61802d8be34d7d15dc84806c6609523bbd1492ce
--- /dev/null
+++ b/base-tutorial/src/main/java/org/sikongsphere/qqnetwork/qqserver/Utility.java
@@ -0,0 +1,168 @@
+package org.sikongsphere.qqnetwork.qqserver;
+
+import java.util.Scanner;
+
+public class Utility {
+ private static Scanner scanner = new Scanner(System.in);
+
+
+ /**
+ * 功能:读取键盘输入的一个菜单选项,值:1——5的范围
+ * @return 1——5
+ */
+ public static char readMenuSelection() {
+ char c;
+ for (; ; ) {
+ String str = readKeyBoard(1, false);//包含一个字符的字符串
+ c = str.charAt(0);//将字符串转换成字符char类型
+ if (c != '1' && c != '2' &&
+ c != '3' && c != '4' && c != '5') {
+ System.out.print("选择错误,请重新输入:");
+ } else break;
+ }
+ return c;
+ }
+
+ /**
+ * 功能:读取键盘输入的一个字符
+ * @return 一个字符
+ */
+ public static char readChar() {
+ String str = readKeyBoard(1, false);//就是一个字符
+ return str.charAt(0);
+ }
+ /**
+ * 功能:读取键盘输入的一个字符,如果直接按回车,则返回指定的默认值;否则返回输入的那个字符
+ * @param defaultValue 指定的默认值
+ * @return 默认值或输入的字符
+ */
+
+ public static char readChar(char defaultValue) {
+ String str = readKeyBoard(1, true);//要么是空字符串,要么是一个字符
+ return (str.length() == 0) ? defaultValue : str.charAt(0);
+ }
+
+ /**
+ * 功能:读取键盘输入的整型,长度小于2位
+ * @return 整数
+ */
+ public static int readInt() {
+ int n;
+ for (; ; ) {
+ String str = readKeyBoard(10, false);//一个整数,长度<=2位
+ try {
+ n = Integer.parseInt(str);//将字符串转换成整数
+ break;
+ } catch (NumberFormatException e) {
+ System.out.print("数字输入错误,请重新输入:");
+ }
+ }
+ return n;
+ }
+ /**
+ * 功能:读取键盘输入的 整数或默认值,如果直接回车,则返回默认值,否则返回输入的整数
+ * @param defaultValue 指定的默认值
+ * @return 整数或默认值
+ */
+ public static int readInt(int defaultValue) {
+ int n;
+ for (; ; ) {
+ String str = readKeyBoard(10, true);
+ if (str.equals("")) {
+ return defaultValue;
+ }
+
+ //异常处理...
+ try {
+ n = Integer.parseInt(str);
+ break;
+ } catch (NumberFormatException e) {
+ System.out.print("数字输入错误,请重新输入:");
+ }
+ }
+ return n;
+ }
+
+ /**
+ * 功能:读取键盘输入的指定长度的字符串
+ * @param limit 限制的长度
+ * @return 指定长度的字符串
+ */
+
+ public static String readString(int limit) {
+ return readKeyBoard(limit, false);
+ }
+
+ /**
+ * 功能:读取键盘输入的指定长度的字符串或默认值,如果直接回车,返回默认值,否则返回字符串
+ * @param limit 限制的长度
+ * @param defaultValue 指定的默认值
+ * @return 指定长度的字符串
+ */
+
+ public static String readString(int limit, String defaultValue) {
+ String str = readKeyBoard(limit, true);
+ return str.equals("")? defaultValue : str;
+ }
+
+
+ /**
+ * 功能:读取键盘输入的确认选项,Y或N
+ * 将小的功能,封装到一个方法中.
+ * @return Y或N
+ */
+ public static char readConfirmSelection() {
+ System.out.println("请输入你的选择(Y/N)");
+ char c;
+ for (; ; ) {//无限循环
+ //在这里,将接受到字符,转成了大写字母
+ //y => Y n=>N
+ String str = readKeyBoard(1, false).toUpperCase();
+ c = str.charAt(0);
+ if (c == 'Y' || c == 'N') {
+ break;
+ } else {
+ System.out.print("选择错误,请重新输入:");
+ }
+ }
+ return c;
+ }
+
+ /**
+ * 功能: 读取一个字符串
+ * @param limit 读取的长度
+ * @param blankReturn 如果为true ,表示 可以读空字符串。
+ * 如果为false表示 不能读空字符串。
+ *
+ * 如果输入为空,或者输入大于limit的长度,就会提示重新输入。
+ * @return
+ */
+ private static String readKeyBoard(int limit, boolean blankReturn) {
+
+ //定义了字符串
+ String line = "";
+
+ //scanner.hasNextLine() 判断有没有下一行
+ while (scanner.hasNextLine()) {
+ line = scanner.nextLine();//读取这一行
+
+ //如果line.length=0, 即用户没有输入任何内容,直接回车
+ if (line.length() == 0) {
+ if (blankReturn) return line;//如果blankReturn=true,可以返回空串
+ else continue; //如果blankReturn=false,不接受空串,必须输入内容
+ }
+
+ //如果用户输入的内容大于了 limit,就提示重写输入
+ //如果用户如的内容 >0 <= limit ,我就接受
+ if (line.length() < 1 || line.length() > limit) {
+ System.out.print("输入长度(不能大于" + limit + ")错误,请重新输入:");
+ continue;
+ }
+ break;
+ }
+
+ return line;
+ }
+}
+
+
diff --git a/base-tutorial/src/test/java/org/sikongsphere/qqnetwork/qqclient/QqClientTest.java b/base-tutorial/src/test/java/org/sikongsphere/qqnetwork/qqclient/QqClientTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..81198c84b2d96b21210ab0d1bd227ebc64ea5e5e
--- /dev/null
+++ b/base-tutorial/src/test/java/org/sikongsphere/qqnetwork/qqclient/QqClientTest.java
@@ -0,0 +1,17 @@
+package org.sikongsphere.qqnetwork.qqclient;
+
+import org.junit.Test;
+import org.sikongsphere.qqnetwork.qqclient.view.View;
+
+/**
+ * @author 徐艺阁
+ * @version 1.0
+ */
+public class QqClientTest {
+ public View view = new View();
+
+ @Test
+ public void showView(){
+ view.showView();
+ }
+}
diff --git a/base-tutorial/src/test/java/org/sikongsphere/qqnetwork/qqserver/QqServerTest.java b/base-tutorial/src/test/java/org/sikongsphere/qqnetwork/qqserver/QqServerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a9a6962ced25e61b118ca53ff06f0234728d8ccb
--- /dev/null
+++ b/base-tutorial/src/test/java/org/sikongsphere/qqnetwork/qqserver/QqServerTest.java
@@ -0,0 +1,15 @@
+package org.sikongsphere.qqnetwork.qqserver;
+
+import org.junit.Test;
+
+/**
+ * @author 徐艺阁
+ * @version 1.0
+ */
+public class QqServerTest {
+
+ @Test
+ public void qqServe(){
+ new QQServer();
+ }
+}