c++网络五子棋Linux版

这次写的是一个网络版五子棋

怎么说的,这次的cpp文件文件比较多,我就贴个github代码吧

github
编译主要看 makefile里那几个文件
实现了 登录 匹配下棋。

服务器用了 epoll+线程池(模仿《linux高性能编程写的》)但这次的教训就是这个棋局的主体业务逻辑应该放在服务器(我写在客户端由客户端判断棋局是否结束),而且线程池处理也是计算密集型任务,在这种俩个用户并非同时下棋的程序中可以不用。更何况放在客户端的业务逻辑可以伪造的,这样服务器就可能收到伪造的数据。

给大家看下效果:
在这里插入图片描述

经验:

  1. 由于用的是PACK的buffer缓存给线程池的process函数执行(同样还有写缓冲), 每次EPOLLIN 读入后需要切换 EPOLLOUT,写出后再切换EPOLLIN,这样就不会多次读入到同一缓冲区了。
  2. c++线程中想要使用类的函数,得需要 thread(clientUser::UI, this).detach();在参数中传入对象的指针,同时这个调用的函数必须得是类内的静态函数,且这个静态函数也只能调用类的静态成员,想要使用对象只能使用传进来的arg 通过clientUser *cu = (clientUser *) arg;再使用cu->xxx来使用cu内的成员
    3.输入出错重新输入的c++方式
while (1) {
    
    
            cin >> ch;
            if (cin.fail()) {
    
    
                std::cout << "输入有误" << std::endl;
                cin.clear();
                cin.ignore();
                continue;
            }
            break;
        }

4.condition_variable中要传锁得是unique_lock ,而不是mutex。
同时从源码可知调用条件变量的wait中可以传入的条件是while(!p)而不是if,也就是条件不满足会重新wait休眠。


    template<typename _Predicate>
      void
      wait(unique_lock<mutex>& __lock, _Predicate __p)
      {
    
    
	while (!__p())
	  wait(__lock);
      }

5.类的静态成员的初始化在类外不能在.h,放其中一个.cpp即可(最好放在类的.cpp内)
6.网络发包的pack中不能出现容器,本来很想用string!
7.make_shared_ptr 的参数是对象而不是对象指针,如果在类中有shared_ptr可以通过构造函数传入的new指针初始化,
8.ET模式下 read是一次读完后出现EAGAIN ,EWOULDBLOCK说明客户发的全部读了(是对的),而我使用包装成Readn恰好读PACK的大小可能不会执行到这一步。
9.匹配可以使用对象指针队列,匹配成功放在一个pair集合,比赛结束或者用户退出则需要在队列和集合等容器中清除对象指针

  1. str = "SELECT * FROM information_schema.SCHEMATA where SCHEMA_NAME='chess'";判断是有chess这个数据库,str = "select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='chess' and TABLE_NAME='account'";判断chess库是否有account表。
  2. 刚看了点设计模式,觉得这个是客户端的客户类是需要设置为单例模式的。并且这次的程序代码复用性不强,本想同时给五子棋类设计的判断胜出规则放在了Table类,而五子棋类的父类ChessBase就显的很累赘rule()没用上,之后再想方法完善,可能是因为不知道围棋的规则,没法实践c++继承体系。

猜你喜欢

转载自blog.csdn.net/adlatereturn/article/details/108046579