博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
本地对弈五子棋(以命名管道进行通信)
阅读量:6963 次
发布时间:2019-06-27

本文共 11819 字,大约阅读时间需要 39 分钟。

 

初步的界面如下:

为了实现不同的窗口、不同进程弈五子棋对弈,就需要在不同进程间的进行通信,我们采用linux底层的命名管道进行通信。

首先我们要进行管道通信头文件的包含、传输数据的结构定义、数据通信操作的函数定义(代码如下):

1 #ifndef MESGOPREAT_H 2 #define MESGOPREAT_H 3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
//O_RDONLY12 #include
//PIPE_BUF13 #include
14 #define MAXLINE 408815 #define FILE_MODE (S_IRUSR | S_IWUSR |S_IRGRP | S_IROTH)16 #define READ_FIFO "/tmp/fifo.test1" //本端用来打开读17 #define WRITE_FIFO "/tmp/fifo.test2"//本端用来打开写18 19 //另一端如下定义20 21 //#define WRITE_FIFO "/tmp/fifo.test1" //本端用来打开读22 //#define READ_FIFO"/tmp/fifo.test2"//本端用来打开写23 //#define24 #define DATASIZE 625 #define MAXMESGDATA (sizeof(struct mymesg) - 2 * sizeof(long))26 #define MESGHDRSIZE (sizeof(struct mymesg) - MAXMESGDATA)27 28 typedef struct mymesg{29 30 long mesg_type;31 long mesg_len_data;32 int data[DATASIZE];33 34 }Mesg;35 Q_DECLARE_METATYPE(Mesg)//用connect函数就需要此宏,和之后的qRegisterMetaType
("Mesg");一同使用36 ssize_t mesg_send(int ,struct mymesg *);//数据发送37 void Mesg_send(int , struct mymesg *);//数据发送38 ssize_t mesg_recv(int , struct mymesg *);//数据接收39 40 #endif // MESGOPREAT_H
MesgOpreat.h

下面是这些函数的实现

1 #include"MesgOpreat.h" 2 ssize_t mesg_send(int fd, Mesg * mptr){ 3  4     return(write(fd, mptr, MESGHDRSIZE + mptr -> mesg_len_data)); 5  6 } 7 ssize_t mesg_recv(int fd, Mesg *mptr){ 8     ssize_t len; 9     ssize_t n;10     if( (n = read(fd, mptr, MESGHDRSIZE)) == 0 ){
//读取头部11 return 0;12 }else if ( n != MESGHDRSIZE){ //头部长度和标准不一致时执行13 printf("mesg header expect %d,got %d\n", MESGHDRSIZE, n );14 return 0;15 }16 if( (len = mptr -> mesg_len_data) > 0){ //在头部中获得传输数据的长度17 if( (n = read(fd, mptr-> data, len)) != len){ //只取得头部数据指定的数据的长度数据18 printf("mesg data expect %d, got %d\n", len, n);19 return 0;20 }21 }22 return n; //返回的是数据部的长度23 24 }25 void Mesg_send(int fd, Mesg *mptr){26 ssize_t n;27 if( (n = mesg_send(fd, mptr)) != mptr -> mesg_len_data + MESGHDRSIZE){28 printf("mesg send error\n");29 return ;30 }31 }
MesgOpreat.cpp

 每一个对弈窗口会因为等待对方发送数据而卡屏,所以我们将这个阻塞的recive操作放在一个单独的线程里,我们自定义了一个类MonitorThread 它是继承QThread

1 #ifndef MONITORTHREAD_H 2 #define MONITORTHREAD_H 3 #include
4 #include
5 #include "MesgOpreat.h" 6 7 class MonitorThread : public QThread 8 { 9 Q_OBJECT10 public:11 MonitorThread(QObject *parent);12 ~MonitorThread();13 void run();14 15 signals:16 void dataArived(Mesg);17 18 protected:19 20 private:21 Mesg mesg;22 int readfifo,dummyfd;23 };24 25 #endif // MONITORTHREAD_H
monitorthread.h

下面是对MonitorThread类中的一些方法的实现

1 #include "monitorthread.h" 2  3 MonitorThread::MonitorThread(QObject *parent) : 4     QThread(parent) 5 { 6     start(); 7 } 8 MonitorThread::~MonitorThread(){ 9     delete this;10 }11 void MonitorThread::run(){12     if( (mkfifo(READ_FIFO, FILE_MODE) < 0) && (errno == EEXIST)){13         printf("can't create %s\n",READ_FIFO);14     }15     if( (mkfifo(WRITE_FIFO, FILE_MODE) < 0) && (errno == EEXIST)){16         printf("can't create %s\n",WRITE_FIFO);17     }18     qDebug()<<"b";19     int n;20     qDebug()<<"d";21     readfifo = open(READ_FIFO, O_RDONLY,0);22     dummyfd = open(READ_FIFO, O_WRONLY,0);//在这里已经阻塞23     qDebug()<<"e";24     while((n = mesg_recv(readfifo, &mesg)) > 0){25         emit dataArived(mesg);26     }27 }
monitorthread.cpp

主窗体类的定义

1 #ifndef CLIENTMAINWINDOW_H 2 #define CLIENTMAINWINDOW_H 3 #define MAPLENTH 10 4 #include 
5 #include
6 #include
7 #include "monitorthread.h" 8 #include"MesgOpreat.h" 9 #include
10 #include
11 #include
12 class ClientMainWindow : public QMainWindow13 {14 Q_OBJECT15 public:16 explicit ClientMainWindow(QWidget *parent = 0);17 ~ClientMainWindow(){18 delete this;19 }20 signals:21 public slots:22 void Mesg_recved(Mesg);23 void Chess_left_Clicked();24 private:/25 int flag = 0;26 int up_col_count = 0, low_col_count = 0, left_row_count = 0,right_row_count = 0,27 left_up_count = 0, right_up_count = 0, left_low_count = 0, right_low_count = 0 ;28 int judge();29 void ergodic(int x, int y);30 void ergodic_up(int x, int y);//基于某一点向上第归遍历31 void ergodic_down(int x, int y);//基于某一点向下第归遍历32 void ergodic_left(int x, int y);//基于某一点向左第归遍历33 void ergodic_right(int x, int y);//基于某一点向右第归遍历34 void ergodic_left_up(int x, int y);//基于某一点向左上第归遍历35 void ergodic_left_low(int x, int y);//基于某一点左下第归遍历36 void ergodic_right_up(int x, int y);37 void ergodic_right_low(int x, int y);38 void Count_to_0();39 int return_judge(int x, int y);//判断第归结束的标志40 /////41 42 int writefifo;43 QPushButton *button[MAPLENTH][MAPLENTH];44 MonitorThread *thread;45 Mesg mesg;46 QGridLayout *layout;47 void Init_Button();48 int map[MAPLENTH][MAPLENTH] = {};49 void StartGame();//创建命名管道与初始打开50 void Listen_thread();51 };52 53 #endif // CLIENTMAINWINDOW_H
clientmainwindow.h

主窗体类中方法的实现

1 #include "clientmainwindow.h"  2   3 ClientMainWindow::ClientMainWindow(QWidget *parent) :  4     QMainWindow(parent)  5 {  6     qDebug()<<"a";  7     this->setGeometry(300,600,494,521);  8     setWindowFlags(windowFlags()& ~Qt::WindowMaximizeButtonHint);//禁止最大化  9     setFixedSize(this->width(), this->height());//禁止最大化 10     StartGame(); 11     qRegisterMetaType
("Mesg"); 12 Init_Button(); 13 } 14 15 void ClientMainWindow:: Chess_left_Clicked(){ 16 qDebug()<<"left"; 17 int p_x, p_y; 18 QPoint Chess_Point; 19 QPushButton* btn= qobject_cast
(sender()); 20 Chess_Point = btn->pos(); 21 p_x = (Chess_Point.y() - 13) / 50; 22 p_y = (Chess_Point.x() - 11) / 48; 23 qDebug()<<"p_x"<
setIcon(QIcon(":/picture/Black.bmp")); 35 map[p_x][p_y]= 2; 36 mesg.mesg_type =1; 37 mesg.mesg_len_data = DATASIZE* sizeof(int); 38 ergodic(p_x, p_y); 39 mesg.data[0] = p_x; 40 mesg.data[1] = p_y; 41 mesg.data[2] = up_col_count + low_col_count + 1; 42 mesg.data[3] = right_row_count + left_row_count + 1; 43 mesg.data[4] = left_up_count + right_low_count + 1; 44 mesg.data[5] = left_low_count + right_up_count + 1; 45 if( (writefifo = open(WRITE_FIFO, O_WRONLY,0)) < 0){ 46 printf("server open writefifo error: %s\n",strerror(errno)); 47 48 } 49 Mesg_send( writefifo, &mesg); 50 if(judge()){ 51 QMessageBox::about(NULL, "wiring","YOU are Winer!"); 52 exit(0); 53 } 54 } 55 void ClientMainWindow::StartGame(){ 56 57 Listen_thread(); 58 59 } 60 61 void ClientMainWindow:: Listen_thread(){ 62 thread = new MonitorThread(this); 63 connect(thread, SIGNAL(dataArived(Mesg)), 64 this, SLOT(Mesg_recved(Mesg))); 65 qDebug()<<"c"; 66 } 67 68 void ClientMainWindow:: Init_Button(){ 69 70 layout = new QGridLayout; 71 int pos_x = 0, pos_y = 0; 72 for(int row = 0; row < MAPLENTH; row++){ 73 for(int col = 0; col < MAPLENTH; col++){ 74 button[row][col] = new QPushButton(this); 75 pos_x = 48 * col + 3; 76 pos_y = 47 * row + 2; 77 button[row][col]->setGeometry(pos_x,pos_y,40,40); //设置button的坐标与大小 78 button[row][col]->setMaximumSize(40,40); 79 button[row][col]->setMinimumSize(40,40); 80 layout->addWidget(button[row][col],row,col); 81 QObject::connect(button[row][col],SIGNAL(clicked()),this,SLOT(Chess_left_Clicked())); 82 } 83 } 84 QWidget * widget = new QWidget(this) ; 85 this->setCentralWidget(widget) ; 86 widget->setLayout( layout) ; 87 } 88 89 90 void ClientMainWindow::Mesg_recved(Mesg _mesg){ 91 92 mesg = _mesg;//获得的消息 93 button[mesg.data[0]][mesg.data[1]]->setIcon(QIcon(":/picture/White.bmp")); 94 map[mesg.data[0]][mesg.data[1] ]= 1; 95 // ergodic(mesg.data[0], mesg.data[1]); 96 if(mesg.data[2] >= 5 || mesg.data[3] >= 5 || mesg.data[4]>= 5 || mesg.data[5] >= 5){ 97 QMessageBox::about(NULL, "wiring","Distinnation is Winer!"); 98 exit(0); 99 }100 flag = 0;101 }102 103 104 105 int ClientMainWindow::judge(){106 if( (up_col_count + low_col_count + 1) >= 5 ||107 (right_row_count + left_row_count + 1) >= 5||108 (left_up_count + right_low_count + 1) >= 5||109 (left_low_count + right_up_count + 1) >= 5){110 return 1;111 }112 Count_to_0();113 return 0;114 }115 116 int ClientMainWindow::return_judge(int x, int y){
//判断第归结束117 if(x < 0 || x >= MAPLENTH || y < 0 || y>= MAPLENTH ){118 return 1;119 }120 return 0;121 }122 void ClientMainWindow::Count_to_0(){123 up_col_count = 0;124 low_col_count = 0;125 right_row_count = 0;126 left_row_count = 0;127 left_up_count = 0;128 right_up_count = 0 ;129 left_low_count = 0;130 right_low_count = 0;131 }132 133 134 void ClientMainWindow::ergodic_right_low(int x, int y){135 if( return_judge(x, y)){136 return;137 }138 if(map[x][y] != 0 && map[x + 1 ][y + 1] == map[x][y]){
//向右下遍历right_low139 right_low_count++;140 ergodic_right_low(x + 1 , y + 1);141 }142 }143 void ClientMainWindow::ergodic_left_low(int x, int y){144 if( return_judge(x, y)){145 return;146 }147 if(map[x][y] != 0 && map[x + 1 ][y - 1] == map[x][y]){
//向左下遍历left_low148 left_low_count++;149 ergodic_left_low(x + 1 , y - 1);150 }151 }152 void ClientMainWindow::ergodic_right_up(int x, int y){153 if( return_judge(x, y)){154 return;155 }156 if(map[x][y] != 0 && map[x - 1 ][y + 1] == map[x][y]){
//向右上遍历right_up157 right_up_count++;158 ergodic_right_up(x - 1 , y + 1);159 }160 }161 void ClientMainWindow::ergodic_left_up(int x, int y){162 if( return_judge(x, y)){163 return;164 }165 if(map[x][y] != 0 && map[x - 1 ][y - 1] == map[x][y]){
//向左上遍历left_up166 left_up_count++;167 ergodic_left_up(x - 1 , y - 1);168 }169 }170 void ClientMainWindow::ergodic_right(int x, int y){171 if( return_judge(x, y)){172 return;173 }174 if(map[x][y] != 0 && map[x][y + 1] == map[x][y]){
//向右遍历right175 right_row_count++;176 ergodic_right(x , y + 1);177 }178 }179 void ClientMainWindow::ergodic_left(int x, int y){180 if( return_judge(x, y)){181 return;182 }183 if(map[x][y] != 0 && map[x][y - 1] == map[x][y]){
//向左遍历left184 left_row_count++;185 ergodic_left(x , y - 1);186 }187 }188 void ClientMainWindow::ergodic_down(int x, int y){189 if( return_judge(x, y)){190 return;191 }192 if(map[x][y] != 0 && map[x + 1][y] == map[x][y]){193 low_col_count++;194 ergodic_down(x + 1, y);195 }196 }197 void ClientMainWindow::ergodic_up(int x, int y){198 if( return_judge(x, y)){199 return;200 }201 if(map[x][y] != 0 && map[x-1][y] == map[x][y]){
//向上查询up202 up_col_count++;203 ergodic_up(x - 1, y);204 }205 }206 void ClientMainWindow::ergodic(int x, int y){ //各个方向进行分治第归遍历207 ergodic_up( x, y);//向上208 ergodic_down( x, y);//向下209 ergodic_left(x, y); //向左210 ergodic_right(x, y);211 ergodic_left_up( x, y);212 ergodic_left_low( x, y);213 ergodic_right_up(x, y);214 ergodic_right_low(x, y);215 }
clientmainwindow.cpp

另一端只需要改变  MesgOpreat.h中的宏READ_FIFO和WRITE_FIFO交换一下就可以与此端通信

 

转载于:https://www.cnblogs.com/sangzaohaishui/p/3923062.html

你可能感兴趣的文章
SI24R2F自带温湿度传感器的2.4g超低功耗蓝牙芯片 完全替代SI24R2E
查看>>
SSM-SpringMVC-23:SpringMVC中初探异常解析器
查看>>
构建之法阅读笔记05
查看>>
SPI
查看>>
字节和字符
查看>>
windows组策略屏蔽
查看>>
html中的相对路径问题
查看>>
Git合并分支或者冲突
查看>>
struts json ajax整理
查看>>
一步一步写平衡二叉树(AVL树)
查看>>
deque与vector的主要区别
查看>>
Ubuntu安装
查看>>
POI简易帮助文档--给Excel设置样式
查看>>
MJRefresh使用
查看>>
FPGA成神之路 ----- 序
查看>>
自学java 第十一章持有对象
查看>>
HDU5781 ATM Mechine(DP 期望)
查看>>
在go中使用json作为主要的配置格式
查看>>
Oracle 11g 安装
查看>>
Python常用模块
查看>>