初步的界面如下:

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

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

 1 #ifndef MESGOPREAT_H
 2 #define MESGOPREAT_H
 3 #include<unistd.h>
 4 #include<sys/types.h>
 5 #include<sys/wait.h>
 6 #include <sys/stat.h>
 7 #include<stdio.h>
 8 #include<stdlib.h>
 9 #include<errno.h>
10 #include<string.h>
11 #include <fcntl.h> //O_RDONLY
12 #include<limits.h> //PIPE_BUF
13 #include <QtCore>
14 #define    MAXLINE 4088
15 #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 //#define
24 #define DATASIZE  6
25 #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>("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<QDebug>
 4 #include <QThread>
 5 #include "MesgOpreat.h"
 6
 7 class MonitorThread : public QThread
 8 {
 9     Q_OBJECT
10 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 <QMainWindow>
 5 #include<QPushButton>
 6 #include<QGridLayout>
 7 #include "monitorthread.h"
 8 #include"MesgOpreat.h"
 9 #include<QDebug>
10 #include<QPoint>
11 #include<QMessageBox>
12 class ClientMainWindow : public QMainWindow
13 {
14     Q_OBJECT
15 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>("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<QPushButton*>(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"<<p_x ;
 24     qDebug()<<"p_y"<<p_y;
 25     if(map[p_x][p_y] != 0){
 26         QMessageBox::about(NULL, "wring", "Occupied");
 27         return;
 28     }
 29     if(flag != 0){
 30         QMessageBox::about(NULL,"woring", "you have inputed");
 31         return;
 32     }
 33     flag = 1;
 34     button[p_x][p_y]->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_low
139         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_low
148         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_up
157         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_up
166         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]){//向右遍历right
175         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]){//向左遍历left
184         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]){//向上查询up
202         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

本地对弈五子棋(以命名管道进行通信)相关推荐

  1. c语言程序实现进程的管道通信,C 进程间通信--命名管道通信代码实现及其原理图示...

    在将这个题目之前大家需要了解几个概念: 进程: 我们可以先看进程的定义:进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础: ...

  2. 进程通信——命名管道

    目录 1.Creat 2.Open 3.Read/Write 4.Wait 5.Close 6.Delete 管道是 SylixOS 进程间通信的一种方式. 管道分为匿名管道 pipe 和命名管道 f ...

  3. 进程间通信 —— 命名管道

    管道包括三种: 1):普通管道PIPE,通常有很多限制,一是半双工,只能单向传输,二是只能在父子进程间使用 2):流管道:这种能双向传输,但是也是只能父子进程间使用. 3):命名管道,去除了以上的第二 ...

  4. 进程间通信 - 命名管道实现

    引子 好,到这里呢,就需要介绍实现进程间通信的第四种方式了, 也就是通过命名管道来实现,前面介绍的那三种方式呢,都是有缺陷或者说局限性太强, 而这里介绍的命名管道相对来说,在这方面就做得好很多了, 比 ...

  5. linux 命名管道 c语言 不同进程,进程间通信 - 命名管道实现

    命名管道概述 命名管道是通过网络来完成进程之间的通信的,命名管道依赖于底层网络接口, 其中包括有 DNS 服务,TCP/IP 协议等等机制,但是其屏蔽了底层的网络协议细节, 对于匿名管道而言,其只能实 ...

  6. 进程间通信(IPC)------- 命名管道

    匿名管道的概述 对于匿名管道而言,命名管道使用了windows安全机制,因而命名管道的服务器端可以控制哪些客户有权与其建立连接.哪些客户端是不能够与这个命名管道建立连接的.命名管道的通信是以连接的方式 ...

  7. 【Linux系统编程】进程间通信之命名管道

    00. 目录 文章目录 00. 目录 01. 命名管道概述 02. 命名管道创建 03. 命名管道特性 04. 命名管道非阻塞 05. 附录 01. 命名管道概述 无名管道,由于没有名字,只能用于亲缘 ...

  8. [转载]使用命名管道实现进程间通信

    使用命名管道实现进程间通信 来源 : VChelp 4.5 进程间通信 在Win32下提供的进程间通信方式有以下几种: 剪贴板Clipboard:在16位时代常使用的方式,CWnd类中提供了支持. C ...

  9. 进程间通信:命名管道FIFO(2)

    一.命名管道 如果我们想在不相关的进程之间交换数据,可以用FIFO文件来完成这项工作,它通常也被称为命名管道.命名管道是一种特殊类型的文件,它在文件系统中以文件名的形式存在,但是它的行为却和我们已经见 ...

最新文章

  1. 分享10个效率实用工具,让你更优雅地使用windows
  2. 常用开发技巧系列(三)
  3. Visual Studio中怎样更改Nuget程序包源
  4. html5中在图片上打字的语法,HTML5 canvas 基本语法
  5. 统计字符串中单词个数的算法优化
  6. linux之彻底卸载mysql
  7. android程序名称,Android应用程序名称带上标
  8. 企业的最佳选择?开放式混合云大行其道
  9. NoSQL之【MongoDB】学习(二):DML和查询操作说明
  10. 17. CSS 框模型概述
  11. 机器学习--组合分类方法之随机森林算法原理和实现(RF)
  12. keras之分类问题和回归问题
  13. php广告统计代码,JS广告、统计代码如何添加,怎样添加JS统计代码和广告
  14. python鼠标监听_用Python监听鼠标和键盘事件
  15. FNN 网络介绍与源码浅析
  16. 墙面有几种装修方法_墙面装修有哪几种常见方法?
  17. 01. 利用正则表达式提取文章中的所有英文单词
  18. 深度学习深度信念网络DBNs—简易详解
  19. 深度解析Java游戏服务器开发
  20. 区块链技术十周年—回眸与前瞻

热门文章

  1. java.lang.UnsupportedClassVersionError: com/wyf/test/non/T : Unsupported major.minor version 52.0
  2. 第六章 程序数据集散地:数据库
  3. RabbitMQ消费失败重试策略、及重试策略应用场景详解
  4. 打开CHM文件出现错误的解决方法
  5. 招商基金数字化转型下的研发管理|ONES 客户案例
  6. didReceiveIQ
  7. 华为计算机笔记本的配置,怎么看笔记本电脑配置 查询笔记本配置方法【详细步骤】...
  8. FCN全卷积网络—upsampling(上采样)——OpenCV图像金字塔
  9. Android 随笔集 By tuliyuan
  10. 来自前端初学者对前端的“初见”