• Beta版本展示博客


    1 团队介绍

    团队组成:

    齐爽爽(258)个人博客:http://www.cnblogs.com/shuangshuangblog/

    马帅(248)个人博客:http://www.cnblogs.com/whu-mashuai/

    何健(267)个人博客:http://www.cnblogs.com/hankin2017/

    蔡凯峰(285)个人博客:http://www.cnblogs.com/cai2017282110285/

    团队Git链接:https://github.com/WHUSE2017/C-team

    2 Bate过程回顾

    2.1 团队项目目标

    (1)预期典型用户:18--40岁在武汉的人,前期只在武汉大学,武大学生。

    (2)预期功能描述:能够发布自己的活动行程、搜索到某时间某地点的活动及参加人员信息。

    (3)预期用户数量:前期500人左右。

    2.2 如何满足用户需求

      只要是本系统的用户,我们都提供活动查询,不过是一件想好取得地点,或者没有想好干什么,但是有时间,都能在系统里面找到想要的信息,即使当时没有找到,你也可以自己做主,发布行程消息,等待其他人的加入。至少我们提供一个集中的平台,更易于找到想找到的人。

      像正常软件一样,用户登录自己的账户,可以直接查看自己的活动行程,也可以点击取消自己的活动,当然,用户最好给系统一个反馈,好让系统的信息更准确。

    2.3 分工与经验教训

      我们分工依然比较粗暴的,

      前台界面:何健;

      逻辑层:蔡凯峰;

      数据库设计与连接以及Alpha版展示与讲解:马帅;

      文档编辑与组员协作:齐爽爽。

      经验教训:

      (1)面对面沟通:依然是加强沟通。因为这个周末,大家都有事情,所以小组会议移交在网上,还是没有面对面来的实在。

      (2)还想用《构建之法》里面的那段:>scrum计划阶段的估计不是一个"合同",领导们不要把它当成一个合同。估计总是不准的。坚持短期的sprint,这样即使不准的估计也不会又打的损害。真的觉得敏捷的sprint还是很有效的。

    2.4 项目管理

      项目管理就是按照老师上课讲的和书上讲的大概中和一下,分工明确,各自领取任务,然后每天汇报。然后具体修改文档发到讨论组。

    2.5 如何做到如期交付

      有计划。主要在前期老师给了两周时间来做分析,把思路计划都已经做好了,所以在冲刺阶段,基本按照前期计划走,有一个计划在那里,所以每天看着燃尽图都有种“革命尚未成功,同志仍需努力”的紧迫感。

      还有小组成员也都很负责。虽然老师任务也很重,但是能熬夜做项目,即使最后交付的东西还不够完善,但是至少能做到,既然咱们干这个事情,就要负责,在规定时间完成自己的任务。

    3 燃尽图

      在上次,是木真正的会使用leangoo,后期修改了时间,所以会有偏差,这次一开始就设置好了所有参数,所以还很很准确的显示了项目完成度,因为全部都没有在计划内完成..........于是在最后一天疯狂的解决问题。

    4 留给后面小组的说明

    项目文件:

     

    文件说明:

    1.SQLStruct.h

    定义了与数据库操作相关的一些结构体:

    struct userStruct;    //用户信息
    struct EventStruct;    //事件信息
    struct StationMessageStruct;    //站内信
    struct ParticipantsStrcut;    //事件参与
    struct SecretSecurityStruct;    //密保
    1

    2.Operate.h/Operate.cpp

    与数据库进行交互的类,类的定义如下:

    class Operate {
    public:
        Operate();
    
        string IntToString(int variable); 
        int StringToInt(string variable);
    
        bool InsertIntoUserTable(userStruct User);    
        bool InsertIntoEventTable(EventStruct Event);    
        bool InsertIntoStationMessageable(StationMessageStruct StationMessage);
        bool UpdateUserTable(userStruct User);//修改用户信息
        bool UpdatePassword(string UserName, string Password);    //修改密码
        bool InsertIntoSecretSecurity(SecretSecurityStruct Security);    //添加密保
        bool joinEvent(int EventID, string username);    //加入活动
        bool setEventState(int Eventid, int State);//设置活动状态    
        SecretSecurityStruct GetSecretSecurity(string UserName);     //获取密保
    
        bool DeleteDataParticipants(int EventID, string UserName);//删除Participants中特定数据
    
        vector<userStruct> LikeUserName(string username);//模糊查找用户名
    
        vector<ParticipantsStrcut> GetParticipantsByUsername(string Username);
        vector<EventStruct> getEventByCondition(string publisher, string participant, int state);
    //查看已发布,或已加入的活动
        string GetPasswordFromUserTable(string username);
        userStruct GetUserDetails(string username);        //获取用户信息
        vector<EventStruct> GetEvent(string StartSite, string EndSite, string StartTime, string EventType);    //搜索活动信息
        vector<EventStruct> GetEventByState(int State);//通过活动状态查询活动
        vector<EventStruct> GetEventByLike(string StartSite, string EndSite);//开始地和结束地模糊查询
        vector<string> GetParticipants(int EventId);//获取活动的参与者
        
        vector<StationMessageStruct> GetMessageBySender(string SenderName);
        vector<StationMessageStruct> GetMessageByReceiver(string ReceiverName);
        EventStruct GetEventDetailById(int EventId);
    public:
        MYSQL mydata;
    };
    2

    3.socket_stream.h/socket_stream.cpp

    处理socket流数据的类,定义如下:

    class socket_stream{
    public:
        enum 
        {
            disconnected,
            connected,
        };    //用来判断socket状态的enum值
        socket_stream(char *ip,unsigned short port);    //客户端构造函数,指定要连接                                                //的远程主机的ip,port
        socket_stream(SOCKET s,sockaddr_in * lpremoteAddr = NULL,int nAddrlen=0);
    //服务端构造函数,将监听到的socket连接传进来,剩下的两个参数
    //可以用来获取socket连接的其他信息
        ~socket_stream();        //析构函数,有些东西需要在这释放掉
        int recvData(char *buffer, int buflen, int flag =0);    //接收流数据
        int sendData(char *buffer, int buflen, int flag =0);    //发送流数据
        int getState();    //获取当前连接的状态
    private:
        void init_cs();    //CRITICAL_SECTION初始化CRITICAL_SECTION结构
        SOCKET sock;    
        int state;
        CRITICAL_SECTION send_cs;    //这两个变量用来锁住对读写缓冲区的操作,避免多个线程同时
        CRITICAL_SECTION recv_cs;    //操作同一个socket连接的读写缓冲区
        sockaddr_in remoteAddr;
        int nAddrlen;
    };
    3

    4.socket_packet.h/socket_packet.cpp

    socket流数据封装成packet

    enum 
    {
        PACKET_LOGIN,
        PACKET_GETXX,
        PACKET_SETXX,
    };
    
    #pragma pack (push,1)   /*指定1字节对齐,有些编译器会补齐成4字节对齐,需要指定1字节对                        齐,否则底层缓冲区可能对数据的长度判断出错*/ 
    typedef struct {
        unsigned int type;        //packet类型
        unsigned int length;        //整个packet的长度
        unsigned int flag;            //附加的标志
        char data[1];            //数据
    }packet_t;
    #pragma pack (pop)      /*还原默认字节对齐*/  
    
    class socket_packet
    {
    public:
        enum
        {
            err_stream_check,
            err_stream_state=-4099,
        };    //在这一层出错时返回的错误标志
        socket_packet(socket_stream *stream);        //构造
        ~socket_packet();            //析构,释放相应内存
        int send_packet(packet_t *packet,int length);        //发送一个packet
        int recv_packet();            //接收一个完整的packet,返回接收的标志
        char *get_buffer();        //接收成功后,用该函数获取packet数据
    private:
        bool check_buffer(packet_t *p);    //检查本类中申请的buffer是否足够大,不足将继续申请                                //内存
        socket_stream *mStream;        //封装在该层的底层类
        char *buffer;            //可变长的缓冲区
        int bufLength;            //缓冲区长度
    };
    4 

    5.session_s.h/session_s.cpp

    一个session的服务端代码,用来获取用户请求和发送处理结果

    class session_s
    {
    public:
        enum {
            disconected,
            have_request,
        };    //判断session的状态
        session_s(socket_packet *sp);    //构造
        ~session_s();    //析构
        bool login(char *username,char*pass);        
        bool _register(void *p);    
        int wait_request();        //等待用户请求
        request_t *get_request();    //获取用户请求    
        bool send_reply(reply_t *reply);    //发送回复
        void login_success(char* name);    //登录成功后设置相关标志
        bool IsLogin(){return this->b_login;}        //判断当前用户是否已经登录
        void setSqlOperate(Operate * o){op=o;}        //设置数据库操作类
        char* getusername(){return username;}        //登录成功后可用来获取当前用户名
        Operate *op;
    private:
        bool b_login;
        char username[128];
        socket_packet *sp;
        request_t request;
        char *reply_buffer;
        char reply_buffer_len;    
    };
    5 

    6.session_c.h/session_c.cpp

    一个session的客户端代码,用来生成、发送用户请求,接收处理结果

    class session_c
    {
    public:
        enum {
            disconected=-1,
            have_request=1,
        };    //session状态
        session_c(socket_packet *sp);
        ~session_c();
        bool login(char *params);
        bool _register(char* params);
        struct userStruct getUserInfo(char *params);
        int wait_reply();    //等待服务端回复
        reply_t *get_reply();    //获取回复结果
        bool SendAndCheck(request_t *req);    //发送requeset并检查当前状态,等待回复
        int getState(){return this->state;};    //获取当前session状态
        bool addEvent(char* params);    //添加活动
        vector<StationMessageStruct> getStationMessage();//获取站内信
        bool addMessage(char *params);    //发送消息
        vector<EventStruct> getEvent(char* params);    //出发地,目的地,时间,活动类型获取活动
        bool joinEvent(char * params);        //参加某个活动
        vector<string> getParticipants(char* params);    //获取某个活动的所有参与者
        EventStruct getEventByID(char* params);    //获取某一个活动
        bool updatauserinfo(char* params);    //修改用户信息
         bool exitEvent(char *params);        //退出某个活动
         bool setEventState(char *parmas);    //设置活动的状态,进行中,完成,取消
         vector<EventStruct> getEventByConditions(char* params);//获取已发布或已加入的活动
         bool setSecurity(char* params);    //设置密保
         string getSecurity(char *params);        //获取密保问题
         string checkSecurity(char *params);    //检查密保回答是否正确,返回密码
    private:
        int send_request(request_t *req);    //发送请求
        int state;        //当前session状态
        socket_packet *sp;    //封装的packet处理类
        bool b_login;    
        reply_t reply;
        char *buffer;
        int bufferlen;
    };
     

    7.request_reply.h

    以上两个session类中所需的一些定义: 

    enum
    {
        TYPE_LOGIN,
        TYPE_REGISTER,
        TYPE_GETUSERINFO,
        TYPE_ADDEVENT,
        TYPE_GETMESSAGE,
        TYPE_ADDMESSAGE,
        TYPE_GETEVENT,
        TYPE_JOINEVENT,
        TYPE_GETPARTICIPANTS,
        TYPE_GETEVENTDETAILBYID,
        TYPE_UPDATEUSERINFO,
        TYPE_EXITEVENT,
        TYPE_SETEVENTSTATE,
        TYPE_GETEVENTBYCONDITIONS,
        TYPE_SETSECURITY,
        TYPE_GETSECURITY,
        TYPE_CHECKSECURITY
    };
    typedef struct{
        int type;
        int flag;
        int datalen;
        char *data;
    }request_t;
    
    typedef struct{
        int type;
        int flag;
        int datalen;
        char *data;
    }reply_t;
    7

    8.UserClient.h/UserClient.cpp

    提供给客户端界面的接口类

    class UserClient
    {
    public:
        UserClient(char *ip, unsigned short port);    //连接服务端的ip,port
        bool Login(char *name,char* password);    //登录
        bool Register(struct userStruct userInfo);    //注册
        int getState(){return this->state;};            //获取session状态
        bool reConnect();                    //重连
        bool fisrtConnect();                    //第一次连接
        struct userStruct getUserInfo(char* username);    //获取用户信息
        bool addEvent(EventStruct Event);                //发布活动
        bool sendMessage(StationMessageStruct message);    //发送消息
        vector<StationMessageStruct> getStationMessage();    //获取站内信
         vector<EventStruct> getEvent(string StartSite, string EndSite, string StartTime,string EventType);
    //获取活动列表
        bool joinEvent(int EventID, string username);            //加入活动
        vector<string> getParticipants(int EventID);            //获取参与者列表
        EventStruct getEventById(int EventID);                //获取活动详情
        void Logout();                                //注销当前用户
        bool UpdateUserInfo(struct userStruct userInfo);        //修改用户信息
         bool ExitEvent(int EventID,string username);        //退出活动
         bool SetEventState(int EventID,int state);            //设置活动状态
         vector<EventStruct> getEventByConditions(string publisher,string participant,int state);
    //获取已发布或已加入的活动
         bool SetSecurity(string username,string sercurity,string answer);
    //设置密保
         string GetSecurity(string username);
    //获取密保问题
         string CheckSecurity(string username,string security,string answer);
    //检查密保回答是否正确,如果正确返回密码
    //服务端会返回密码
    private:
        int state;
        session_c* sc;        //封装的session类
        char mIp[16];
        unsigned short mPort;
        char *buffer;
        int bufferlen;
    };
    View Code

    9.Service.h/Service.cpp

    服务端服务代码

    class Service
    {
    public:
        enum{
            failed,
            success,
        };        //当前服务状态
        Service(unsigned short port);    //构造要监听的端口
        ~Service();    //析构
        int get_state(){return state;};        //获取当前服务状态
        void start_loop();                //开始循环,等待连接
        void setSqlOperate(Operate *o){op=o;}    //设置数据库操作类
        Operate *getSqlOperate(){return op;};    //获取数据库操作类
    private:
        Operate *op;
        socket_packet *sp;
        int state;
        SOCKET slisten;
        void  new_connect_handler(SOCKET);        //每一个新连接都会生成一个新线程处理
    };
    View Code

    10.serverthread.h

    处理每个连接的线程逻辑代码

    DWORD WINAPI myServerThread(LPVOID lpParam)
    {    /*每一个连接都会有一个这样的处理线程*/
        ServerThreadParam *lp =(ServerThreadParam*)lpParam;
        session_s *s = lp->session;
        while(1)
        {
            int state = s->wait_request();
            if (state == s->disconected)
                break;
            request_t * req = s->get_request();    //获取请求
    //根据不同的请求类型,调用不同的处理逻辑(service_xxx)。
            switch(req->type)
            {
            case (TYPE_LOGIN):
                {
                    service_login(s,req);
                    break;
                }
            case(TYPE_REGISTER):
                {
                    service_register(s,req);
                    break;
                }
            case(TYPE_GETUSERINFO):
                {
                    service_getuserinfo(s,req);
                    break;
                }
            case(TYPE_ADDEVENT):
                {
                    service_addevent(s,req);
                    break;
                }
            case(TYPE_GETMESSAGE):
                {    
                    service_getmessages(s,req);
                    break;
                }
            case(TYPE_ADDMESSAGE):
                {
                    service_addmessage(s,req);
                    break;
                }
            case(TYPE_GETEVENT):
                {
                    service_getevent(s,req);
                    break;
                }
            case(TYPE_JOINEVENT):
            {
                service_joinevent(s,req);
                break;
            }
            case(TYPE_GETPARTICIPANTS):
            {
                service_getparticipants(s,req);
                break;
            }
            case(TYPE_GETEVENTDETAILBYID):
                {
                    service_geteventdetail(s,req);
                    break;
                }
            case(TYPE_UPDATEUSERINFO):
                {
                    service_updateuserinfo(s,req);
                    break;
                }
            case(TYPE_EXITEVENT):
                {
                    service_exitevent(s,req);
                    break;
                }
            case(TYPE_SETEVENTSTATE):
                {
                    service_seteventstate(s,req);
                    break;
                }
            case(TYPE_GETEVENTBYCONDITIONS):
                {
                    service_geteventbycondition(s,req);
                    break;
                }
            case(TYPE_SETSECURITY):
                {
                    service_setsecurity(s,req);
                    break;
                }
            default:
                break;
            }
        }
        return 0;
    }
    View Code

    5 运行说明

      https://pan.baidu.com/s/1eSnfZIM

  • 相关阅读:
    @ResponseBody和@RequestBoby的作用
    项目Alpha冲刺Day9
    项目Alpha冲刺Day8
    项目Alpha冲刺Day7
    设计模式第三次作业
    项目Alpha冲刺Day6
    树莓派历程笔记
    项目Alpha冲刺Day5
    django获取ip与数据重复性判定
    在django模板中添加jquery
  • 原文地址:https://www.cnblogs.com/shuangshuangblog/p/7794576.html
Copyright © 2020-2023  润新知