WeTalk --在线群聊程序

团队博客

服务器一直在运行,使用客户端可直接登入使用。(做得很粗糙...)

客户端下载(java环境下直接运行)

0.项目介绍

现在我们网上交流离不开微信和QQ,当然在方便的同时也有风险,像在大企业内部而言,用QQ,微信等,容易造成信息泄露,进而造成巨大的损失,这个时候一个只用于企业内部交流的系统的重要性就凸显出来了。所以我们小组决定做一个在线群聊系统。

1 团队名称、团队成员介绍(需要有照片)

WT队

成员:

网络1513 王威(201521123076)

网络1512 倪兢飞(201521123061)

网络1513 秦贞一(201521123072)

2 项目git地址

项目地址(http://git.oschina.net/SlickGhostjava/wetalk/tree/master/

3 项目git提交记录截图(要体现出每个人的提交记录、提交说明),老师将点击进去重点考核。

王威

秦贞一

倪兢飞

4 项目功能架构图与主要功能流程图

4.0项目分析及规划:

系统分为两大类,客户端和服务器,客户端就是用户使用的部分,有登录界面,注册界面,菜单界面,聊天界面。对于服务器,主要作用为维护数据库以及处理客户端的消息,有如登入验证,用户注册,消息转发等。

本次项目主要涉及到Swing,输入输出流,socket,数据库相关内容。Swing设计界面,socket和输入输出用于实现客户端和服务端之间的消息收发,数据库模块用于信息管理。

根据实际情况,每个人擅长的部分,合理分配任务。

4.1.客户端与服务端功能模块设计

4.2.通信协议设计

本次实现的是一个面向小群体的在线群聊系统,考虑到用户访问量不大,所以涉及到的连接均采用基于TCP的安全可靠通信模型。 以后若要实现用户之间的单聊,可采用UDP通信协议。

4.3.表设计:

  • 用户信息表(users)
字段 解释 类型 字段长度
number 账号 int 5
password 密码 Nvarchar 15
netName 网名 Nvarchar 40
sign 签名 Nvarchar 40
telephone 电话 Nvarchar 11
isVIP 是否会员 int 1

4.4.流程图

5 项目运行截图

服务端启动:

日志文件记录相关信息

客户端运行截图

首先进入登录界面



若该账号没有注册则提示错误



点击注册按钮,进入注册界面



注册成功后,登录:



登录成功,跳出聊天界面:



点击加入群聊:



此时要是再有人加入:



群成员那边有提示,

此时进行聊天:

2017-6-26,增加文件上传下载功能,使用缓冲,利用DataOutputStream和DataInputStream在套接字中传输

因为服务器放在TX云主机上,而且现在网速略慢...传到一半手动给终止了,只接受到3721KB。假如架设在局域网内,那么传输速度是很快的。在本机上测试,200+MB文件大概10s多。

下载文件

6 项目关键代码(不能太多)

客户端:

/*
 *
 * 初始化客户端
 * 功能:
 * 1.建立socket连接
 * 2.返回登入验证结果
 * 3.返回是否注册成功结果
 *
 * @author Wang
 *
 * 2017-6-21
 *
 * update:2017-6-26
 */

public class initClient  {

    public ClientReadThread getReadThread() {
        return readThread;
    }

    public void setReadThread(ClientReadThread readThread) {
        this.readThread = readThread;
    }

    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public void setObjectout(ObjectOutputStream objectout) {
        this.objectout = objectout;
    }

    public void setObjectin(ObjectInputStream objectin) {
        this.objectin = objectin;
    }

    ClientReadThread  readThread;
    Socket socket;
    private ObjectOutputStream objectout;
    private ObjectInputStream objectin;
    private int port = 7890;
    private User user;
//  private String address = "127.0.0.1";
    private String address = "119.29.19.94";
    private String downloadFilePath = "H:\\Client\\";

    //重新连接
        public initClient() {
            try {
                this.Connection();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }

        public ObjectOutputStream getObjectout() {
            return objectout;
        }

        public ObjectInputStream getObjectin() {
            return objectin;
        }

        public void Connection() throws IOException{
             try {

                 socket = new Socket(address, port);
            } catch (IOException e) {
                e.printStackTrace();
            }
                objectin = new ObjectInputStream(socket.getInputStream());
                objectout = new ObjectOutputStream(socket.getOutputStream());

        }

        //验证用户
        public boolean sendUserToServerLogin(User user) throws IOException, ClassNotFoundException{
            String str = new String("login");
            objectout.writeObject(str);
            objectout.flush();

            objectout.writeObject(user);
            objectout.flush();
             //输入对象, 一定要flush()

            //验证结果
            while(true){
                String msg = objectin.readObject().toString();
                System.out.println(msg);
               if(msg.equals("true")){
                   return true;

               }
               else {
                   socket.close();
                   return false;
               }
            }
        }

        //注册用户
        public boolean sendUserToServerRegister(User user) throws IOException, ClassNotFoundException{

            objectout.writeObject("register");
            objectout.flush();

            objectout.writeObject(user);
            objectout.flush();
             //输入对象, 一定要flush()

            //返回是否注册成功
            while(true){
                String msg = objectin.readObject().toString();
               if(msg.equals("true")){
                  // socket.close();
                   return true;

               }
               else {
                   socket.close();
                   return false;
               }
            }
        }

        //加载用户信息
        public User loadUser(Integer number) throws IOException, ClassNotFoundException{

            objectout.writeObject("loadUser");
            objectout.flush();

            objectout.writeObject(number);
            objectout.flush();
            while(true){
                Object obj = objectin.readObject();
               if(obj instanceof User){
                user = (User) obj;
                socket.close();
                return user;
               }
               else {
                   socket.close();
                   return null;
               }
            }
        }

        //成功进入群聊后,开启监听线程
        public boolean enterGroup(User user,ChatJFrame chatFrame) throws IOException, ClassNotFoundException{

            objectout.writeObject("enterGroup");
            objectout.flush();

            System.out.println(user);
            objectout.writeObject(user);
            objectout.flush();

            System.out.println("flush");
                    //开启监听线程
            this.startClintReadThread(chatFrame);
            return true;

        }

        //监听线程
        public void startClintReadThread(ChatJFrame chatFrame){

            readThread = new ClientReadThread(objectin,chatFrame);
            readThread.start();
        }

        //退出群聊
        public void quitGrpou(){
            try {
                objectout.writeObject("quitGroup");
                objectout.flush();

                //关闭监听线程
                readThread.interrupt();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
        //退出客户端
        public void quitWTClient(){
            try {
                objectout.writeObject("quit");
                objectout.flush();

                //关闭监听线程
                socket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

        //发送文件至服务器
        public void sendFlieToServer(String fileName) throws ClassNotFoundException{
            try {
                Connection();
                //要发送的文件绝对路径
                File file=new File(fileName);
//              System.out.println(fileName);
                objectout.writeObject("sendFileToServer");
                objectout.flush();
                //文件名
                objectout.writeObject(file.getName());
                objectout.flush();
                DataOutputStream dos=new DataOutputStream(socket.getOutputStream());

                DataInputStream dis=new DataInputStream(
                        new BufferedInputStream(new FileInputStream(fileName)));

                //缓冲区
                int buffferSize=1024;
                byte[]bufArray=new byte[buffferSize]; 

                while (true) {
                    int read = 0;
                    if (dis!= null) {
                      read = dis.read(bufArray);
                    }   

                    if (read == -1) { 

                      break;
                    }
                    dos.write(bufArray, 0, read);
                  }
                  dis.close();
                  dos.flush();
                  dos.close();
                 this.socket.close();

                      JOptionPane.showMessageDialog(null, "上传成功",
                            "提示 ", JOptionPane.ERROR_MESSAGE);

            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        public void downloadFileFromServer(String fileName) throws IOException {
            objectout.writeObject("downloadFileFromServer");
            objectout.flush();

            objectout.writeObject(fileName);
            objectout.flush();

              DataInputStream   dis = new DataInputStream(new BufferedInputStream(
                      this.socket.getInputStream()));   

              int bufferSize = 1024;
                // 缓冲区
                byte[] buf = new byte[bufferSize];  

                //写入文件至目录
                DataOutputStream fileOut = new DataOutputStream(
                        new BufferedOutputStream(new BufferedOutputStream(
                            new FileOutputStream(downloadFilePath+fileName))));

                while (true) {
                    int read = 0;   

                    if (dis!= null) {
                      read = dis.read(buf);
                    }   

                    if (read == -1) {
                      break;
                    }
                    fileOut.write(buf, 0, read);
                }
                  fileOut.close();
                  JOptionPane.showMessageDialog(null, "下载成功,保存在目录H:\\Client\\",
                            "提示 ", JOptionPane.ERROR_MESSAGE);
        }

}

/*
 *
 * UserDao模式实现类
 * 功能
 * 1.检验登入功能
 * 2.注册功能
 * 3.加载用户信息
 * 4.进入群聊后启动监听线程
 * 5.文件上传与下载
 *
 */
public class ClientUserDaoimpl implements ClientUserDao {

    public ClientUserDaoimpl(){

    }

    public initClient getNewClient() {
        return newClient;
    }

    public void setNewClient(initClient newClient) {
        this.newClient = newClient;
    }

    private initClient newClient;
    @Override
    public boolean Login(User user) {

         newClient = new initClient();

        try {

         //查看返回结果
         if(newClient.sendUserToServerLogin(user))return true;
         else return false;

        } catch (IOException e) {

            e.printStackTrace();
        } catch (ClassNotFoundException e) {

            e.printStackTrace();
        }
        return false;
    }

    @Override
    public boolean Register(User user) {
         newClient = new initClient();

         try {
            if(newClient.sendUserToServerRegister(user))return true;
             else return false;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return false;
    }

    @Override
    public User loadUser(int number) {
        try {
            newClient = new initClient();
            return newClient.loadUser(number);

        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public boolean enterGroup(User user,ChatJFrame chatFrame) {
        try {
            newClient = new initClient();
            chatFrame = new ChatJFrame(this);
            chatFrame.setVisible(true);
            return newClient.enterGroup(user,chatFrame);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public void quitGroup() {
        newClient.quitGrpou();

    }

    public void quitWTClient(){
        newClient.quitWTClient();
    }

    @Override
    public void sendFileToServer(String fileName) {
        try {
            newClient = new initClient();
            newClient.sendFlieToServer(fileName);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public void downloadFileFromServer(String fileName) throws IOException {
        newClient = new initClient();
        newClient.downloadFileFromServer(fileName);

    }

}

服务端

//初始化配置
public class InitAll {
    //服务器存储文件位置
//  public  String serverFliePath = "F:\\";
    public  String serverFliePath = "/java/WTServerFiles/";
    //  重新连接次数
    public  int reconnect = 3;

    //  数据库用户名密码
//  public static String dbUserName = "root";
//  public static String dbPassword = "root";
    public static String dbUserName = "user_user";
    public static String dbPassword = "...";

    //日志保存位置
//  public String logPath = "H://Serverlog.log";
    public String logPath = "/java/Serverlog.log";

}

/*
 *
 * 服务端主线程
 * 实例化的时候建立连接
 * 运行后开启监听
 * @author Wang
 * 2017-6-20
 * update 6-26
 */
public class MainThread extends Thread{
    //在线用户列表
    public static final List<ServerReadThread>
    onLineUserList = new ArrayList<ServerReadThread>();
    ServerReadThread serverReadThread;
    ServerSocket serverSocket;
    Socket socket;
    boolean isStop;
    //同时开启UDPServer
//  UDPServer udpServer;

    public MainThread(){
//      udpServer = new UDPServer(this);
        int port = 7890;
        try {
            //建立服务
             serverSocket = new ServerSocket(port);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }

@Override
public void run() {

    while(isStop==false){
    //监听
     try {
        socket = serverSocket.accept();

        serverReadThread = new ServerReadThread(this,new InitAll());
        serverReadThread.start();

    } catch (IOException e) {
        e.printStackTrace();
    }
    }
}

}

    /*
 *
 * 服务器消息监听线程
 * 通过标识来实现不同功能
 * 2017-6-20
 *
 * update:2017-6-20
 * 增加文件读取
 *
 */
public class ServerReadThread extends Thread {
    //服务器文件存储位置

    String serverFliePath;
    ObjectOutputStream objectout;
    ObjectInputStream  objectin;
    MainThread mainThread;
    boolean flag;
    int reconnect;
    ServerUserDaoJDBCImpl serverUserDaoJDBCImpl;
    User user;
    String mgs;
    Object obj;
    InitAll init;

    //初始化文件存储位置等配置...
    private void initThis(){

        this.serverFliePath = init.serverFliePath;
        this.reconnect = init.reconnect;
    }

    public ServerReadThread(MainThread mainThread,InitAll init){
    this.init = init;
    initThis();

    this.mainThread = mainThread;
    serverUserDaoJDBCImpl = new ServerUserDaoJDBCImpl();
    try {
        objectout = new ObjectOutputStream(mainThread.socket.getOutputStream());
        objectin = new ObjectInputStream(mainThread.socket.getInputStream());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
@Override
    public void run() {
        while(Thread.interrupted()==false){
            if(reconnect < 0){System.out.println("break connect " );try {
                mainThread.socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }break;}
            else{
            try {
//               System.out.println("当前线程个数0000="+ mainThread.onLineUserList.size());

                    obj = objectin.readObject();
                    if(obj!=null)
                     mgs = obj.toString();
                    System.out.println(this.mainThread.socket.getInetAddress() +":"+
                            this.mainThread.socket.getPort() + " request:" +mgs);

                    //0.关闭请求
                     if(mgs.equals("quit"))destoryThread(mgs);

                      //1.登入请求,接收到一个User对象,验证其用户名和密码
                      if(mgs.equals("login")){
                          if((obj = objectin.readObject()) !=null && obj instanceof User){
                              User user = (User)obj;
                              if(serverUserDaoJDBCImpl.checkUser(user)){
                                  ServerRunLog.log.info("User("+user.getNumber()+") Login." );
                              objectout.writeObject("true");
                              objectout.flush();
                              destoryThread(mgs);
                              }
                              else{
                                  objectout.writeObject("false");
                                  objectout.flush();
                                  destoryThread(mgs);
                              }
                          }
                      }

                      //2.注册请求,接收到一个User对象,如果插入数据库成功,则返回ture
                      if(mgs.equals("register")){
                          if((obj = objectin.readObject()) !=null){
                              User user = (User)obj;
                              if(serverUserDaoJDBCImpl.writeUser(user)){
                            ServerRunLog.log.info("Add User:"+user);
                              objectout.writeObject("true");
                              objectout.flush();
                              destoryThread(mgs);
                              }
                              else{
                                  objectout.writeObject("false");
                                  objectout.flush();
                                  destoryThread(mgs);
                              }
                          }
                      }

                    //3.用户要进入群聊提示,接收到一个user对象,用来业务处理(告知其他用户等)
                      if(mgs.equals("enterGroup")){

                          if((obj = objectin.readObject()) !=null ){
                              User user = (User)obj;
                              this.user = user;

                              //若有用户进入群聊,则将其地址和端口加入HashMap
                              MainThread.onLineUserList.add(this);

                              String message = null;
                              if(user.getIsVip() == 0)
                                  message = user.getNetName()+ " 进入了群聊室\n";
                              else message = "尊贵的 " + user.getNetName()+ " 进入了群聊室\n";

                              //遍历List,获取所有进入群聊用户线程,用于发送消息
                              for (int i = 0; i < MainThread.onLineUserList.size(); i++) {
                            MainThread.onLineUserList.get(i).objectout.writeObject("welcomeMessage");
                            MainThread.onLineUserList.get(i).objectout.flush();
                            // System.out.println("当前线程个数1="+MainThread.onLineUserList.size());
                            MainThread.onLineUserList.get(i).objectout.writeObject(message + "\n");
                            MainThread.onLineUserList.get(i).objectout.flush();
                            }
                            }
                          }

                      //4.加载用户信息请求
                      if(mgs.equals("loadUser")){
                          if((obj = objectin.readObject()) !=null && obj instanceof Integer){

                              Integer number = (Integer)obj;
                              User user = serverUserDaoJDBCImpl.loadUser(number);

                              objectout.writeObject(user);
                              objectout.flush();
                              destoryThread(mgs);
                              }
                              else{
                                  objectout.writeObject("false");
                                  objectout.flush();
                                  destoryThread(mgs);
                              }
                          }

                      //5.下线
                      if(mgs.equals("quitGroup")){
                          MainThread.onLineUserList.remove(this);
                            System.out.println("当前群聊在线人数"+
                                    MainThread.onLineUserList.size());
                      }

                      //6.普通信息
                      if(mgs.equals("message")){

                        String groupMsg = user.getNetName() + ": " + objectin.readObject().toString();

                        for (int i = 0; i < MainThread.onLineUserList.size(); i++) {
                        MainThread.onLineUserList.get(i).objectout.writeObject("groupMessage");
                        MainThread.onLineUserList.get(i).objectout.flush();
                        //System.out.println("当前线程个数1="+ MainThread.onLineUserList.size());
                        MainThread.onLineUserList.get(i).objectout.writeObject(groupMsg + "\n");
                        MainThread.onLineUserList.get(i).objectout.flush();
                        }

                        }

                      //下载文件,查看文件目录
                      if(mgs.equals("browseFiles")){
                          File file = new File(serverFliePath);
                          System.out.println(file.getName());
                          destoryThread(mgs);

                      }

                      if(mgs.equals("downloadFileFromServer")){
                          //接受文件名

                          String fileName = serverFliePath+objectin.readObject().toString();
                          File file=new File(fileName);
                          DataOutputStream dos=new DataOutputStream(
                                  mainThread.socket.getOutputStream());

                        DataInputStream dis=new DataInputStream(
                                new BufferedInputStream(new FileInputStream(fileName)));

                        //缓冲区
                        int buffferSize=1024;
                        byte[]bufArray=new byte[buffferSize]; 

                        while (true) {
                            int read = 0;
                            if (dis!= null) {
                              read = dis.read(bufArray);
                            }   

                            if (read == -1) { 

                              break;
                            }
                            dos.write(bufArray, 0, read);
                          }
                          dis.close();
                          dos.flush();
                          dos.close();
                          System.out.println("transFile"+fileName+"succeed");
                          destoryThread(mgs);
                      }

                      //上传文件,把文件添加到服务器
                      if(mgs.equals("sendFileToServer")){

                          if((obj = objectin.readObject()) !=null){

                             //接受文件名信息
                          String fileName = obj.toString();

                          DataInputStream   dis = new DataInputStream(new BufferedInputStream(
                                  mainThread.socket.getInputStream()));   

                          int bufferSize = 1024;
                            // 缓冲区
                            byte[] buf = new byte[bufferSize];  

                            //写入文件至目录
                            DataOutputStream fileOut = new DataOutputStream(
                                    new BufferedOutputStream(new BufferedOutputStream(
                                        new FileOutputStream(serverFliePath+fileName))));

                            while (true) {
                                int read = 0;   

                                if (dis!= null) {
                                  read = dis.read(buf);
                                }   

                                if (read == -1) {
                                  break;
                                }
                                fileOut.write(buf, 0, read);
                            }
                              fileOut.close();
                              //读取结束

                              destoryThread(mgs);
                          }
                      }

               }//try结束
            catch (IOException e) {
            flag = true;
            reconnect--;
            e.printStackTrace();

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    //invalid type code: AC
   //同一个线程里面多次用了用了new objectOutputStream(socket.getOutputStream());
            }
        }
    }
    private void destoryThread(String msg){

            //System.out.println(msg + " request cause destory");
            this.interrupt();

    }
}

/*
 *
 * ServerUserDao模式
 * 1.注册用户writeUser
 * 2.读取用户信息loadUser
 * 3.修改密码modifyPassword
 * 4.修改网名modifyUsername
 * 5.修改签名modifySign
 * 6.验证用户checkUser
 */

public interface ServerUserDao {
    public boolean writeUser(User user);
    public User loadUser(int number);
    //public boolean createFile(User user);
    public boolean modifyUsername(User user);
    public boolean modifyPassword(User user);
    //public boolean modifySign(User user);
    public boolean checkUser(User user);

}  

7 尚待改进或者新的想法

由于时间有限,只实现单一的群聊功能,以后可以陆续添加单聊,文件共享等功能

聊天过程使用UDP,建立几张用户关系表,登入等请求使用现在已经完成的TCP部分,就可以实现单聊。文件上传下载使用TCP,利用缓冲技术加速。

对于账号查询功能:

8 团队成员任务分配,团队成员课程设计博客链接(以表格形式呈现),标明组长。

组员 负责模块 个人博客地址
王威(组长) 总体布局以及实现群聊,文件共享功能 slickghost
倪兢飞 数据库相关模块 JMUNJF
秦贞一 界面设计与实现 wish-tree

We Talk -- 团队博客的更多相关文章

  1. BAT 技术团队博客

    1. 美团技术团队博客:  地址: http://tech.meituan.com/ 2. 腾讯社交用户体验设计(ISUX) 地址:http://isux.tencent.com/ 3. 京东设计中心 ...

  2. 2014年团队博客TOP10

    2014年通过这个团队博客,葡萄城共输出了51篇原创技术博客(含翻译),总阅读超过9万人次,约有1万人次是通过RSS订阅方式阅读,总评论超过500人次. 这里我们通过阅读排序,选出2014年团队博客T ...

  3. 必应缤纷桌面的必应助手-软件分析和用户市场需求之-----二.体验部分 Ryan Mao (毛宇11061171) (完整版本请参考团队博客)

    <必应缤纷桌面的必应助手> 2.体验部分 Ryan Mao (毛宇11061171) (完整分析报告请参考团队博客http://www.cnblogs.com/Z-XML/) 我花了2天的 ...

  4. 团队博客——Sprint计划会议1

    每日Scrum:第一天 会议时间:4.14.晚八点半 会议地点:基础教学楼一楼大厅 小组成员:郭庆樑,林彦汝,张金 认领人—使团队成员分工合作,保持团队的积极性. ID 名称(NAME) 重要性(IM ...

  5. java课程设计--猜数字(团队博客)

    java课程设计--猜数字(团队博客) 1.团队名称以及团队成员介绍 团队名称:cz 团队成员:陈伟泽,詹昌锦 团队照片: 2.项目git地址 http://git.oschina.net/Devil ...

  6. JAVA课程设计——团队博客

    JAVA课程设计--团队博客 1. 团队名称.团队成员介绍(需要有照片) 团队名称:"小羊吃蓝莓"小游戏 团队成员介绍: 成员 班级 学号 廖怡洁 网络1513 201521123 ...

  7. Java课程设计 学生基本信息管理系统 团队博客

    学生基本信息管理系统团队博客 项目git地址 https://git.oschina.net/Java_goddess/kechengsheji 项目git提交记录截图 项目功能架构图与主要功能流程图 ...

  8. Do Now 一个让你静心学习的APP——团队博客

    Do Now 一个让你静心学习的APP 来自油条只要半根团队的智慧凝聚的产物! 团队博客总目录: 团队作业第一周 团队作业第二周 Do Now -- 团队冲刺博客一 Do-Now-团队Scrum 冲刺 ...

  9. 团队博客-第六周:Alpha阶段项目复审(科利尔拉弗队)

    团队的排名-点评:以下排名点评谨代表个人观点,如有冒犯,评论联系删除 小组名字和链接 优点 缺点,bug报告(至少140字) 最终名次(无并列) 中午吃啥队 微信小程序应用,新型app会是一个便利的使 ...

随机推荐

  1. RabbitMQ 使用(一)

    RabbitMQ中的使用 这篇文章将会介绍关于RabbbitMQ的使用,并且使用的是kombo(客户端的Python实现)来实现: 安装 如果使用的是mac安装的话,可以先安装到指定的位置,接着配置命 ...

  2. Qt日常备注(函数/接口实现)

    1.判断QString是否为纯数字 2.查找自身最长重复子字符串 3.树形列表复选框操作 4.更改文件权限 5.判断系统64位 6.文件生成md5值 7.版本号比较(字符串比较) //-----实现- ...

  3. ASP.NET MVC5写.php路由匹配时的问题 ASP.NET MVC 4 在 .NET 4.0 与.NET 4.5 的專案範本差異

    由于外包公司结束合作,所以考虑把其APP服务替换过来,因原后台是用php写的,在不影响员客户端使用的情况下在MVC下重写路由配置实现处理原php链接地址的请求,但实现时发现怎么也匹配不到自己写的路由, ...

  4. 微信小程序源码推荐

    wx-gesture-lock  微信小程序的手势密码 WXCustomSwitch 微信小程序自定义 Switch 组件模板 WeixinAppBdNovel 微信小程序demo:百度小说搜索 sh ...

  5. testNG java.net.SocketException: Software caused connection abort: socket write error

    执行用例报错,提示 java.net.SocketException: Software caused connection abort: socket write error java.net.So ...

  6. JS中的函数、BOM和DOM操作

     一.JS中的函数 [关于注释] /** [文档注释]:开头两个*.写在函数上方,在调用函数时可以看到文档上方的描述信息. */   // 单行注释 /* 多行注释 */ 1.函数的声明及调用 (1) ...

  7. 【Regular Expression】RE分类及案例

    背景知识 正则表达式分为三类:基础正则表达式.扩展正则表达式.Perl正则表达式(Perl内建) 通俗来说,这三个一个比一个强大,支持的规则匹配字符更多 1.匹配IP ip addr | grep - ...

  8. .net 中常用的正则表达式整理

    相信很多伙伴都跟我一样有关于正则表达式的爱和恨,怎么说呢? 因为正则表达式规则繁多且复杂,想一个一个学 全部精通,需要耗费很长时间和精力, 但是我们用的地方并不是很多,所以我觉得这类东西需要做成类似工 ...

  9. LNMP1.4环境中安装fileinfo插件

    安装前: 安装前建议先执行 /usr/local/php/bin/php -m (此命令显示目前已经安装好的PHP模块)看一下,要安装的模块是否已安装. 然后下载当前PHP版本的源码并解压. 安装: ...

  10. oracle导库

    cmd窗口直接输入导库命令即可,不需要进入sqlplus C:\Documents and Settings\Administrator> imp username/pass@orcl file ...