基于QTcpSocket和QTcpServer的Tcp通訊以及QDataStream序列化數據

最近要在QT下開發Tcp通訊,發送序列化數據以便于接收。

這里涉及到幾個問題:

1.QTcpSocket、QTcpServer的通訊

2.QDataStream序列化數據

?

多的不說,直接上干貨!!!

?

?

客戶端:

tcpclient.h

 1 #ifndef TCPCLIENT_H
 2 #define TCPCLIENT_H
 3 
 4 #include <QMainWindow>
 5 #include <qt4/Qt/qtcpsocket.h>
 6 #include <Qt/qhostinfo.h>
 7 #include <QDataStream>
 8 #include <QtNetwork>
 9 
10 
11 
12 struct Control_Motor
13 {
14     int length;
15     int command;
16     QString data;
17 };
18 
19 
20 class Motor
21 {
22 public:
23     Motor(){}
24     Motor(int speed,int accele_speed,int p_some)
25     {
26         m_speed = speed;
27         m_accele_speed = accele_speed;
28         m_p_some = p_some;
29     }
30 
31 
32 
33 public:
34     int getV(){return m_speed;}
35     int getA(){return m_accele_speed;}
36     int getP(){return m_p_some;}
37 
38     void setV(const int v){m_speed = v;}
39     void setA(const int a){m_accele_speed = a;}
40     void setP(const int p){m_p_some = p;}
41 
42 
43 
44 public:
45     //friend QDataStream & operator <<(QDataStream &out,const Motor &motor);
46     //friend QDataStream & operator >>(QDataStream &in,Motor &motor);
47     /*
48     friend QDataStream & operator <<(QDataStream &out,Motor &motor)
49     {
50         out << motor.m_speed<<motor.m_p_some<<motor.m_accele_speed;
51         qDebug()<< motor.m_speed<<motor.m_p_some<<motor.m_accele_speed<<"Enter in this";
52         return out;
53     }
54     */
55 public:
56     int m_speed;
57     int m_accele_speed;
58     int m_p_some;
59 
60 };
61 
62 
63 namespace Ui {
64 class TcpClient;
65 }
66 
67 class TcpClient : public QMainWindow
68 {
69     Q_OBJECT
70 
71 public:
72     explicit TcpClient(QWidget *parent = 0);
73     ~TcpClient();
74 
75 private:
76     Ui::TcpClient *ui;
77     QTcpSocket *tcpClient;
78 
79 
80 private slots:
81     void slotConnect();
82     void readMessage();
83     void displayError(QAbstractSocket::SocketError);
84     void sendMessage();
85 
86 
87 
88 public:
89     Control_Motor control_Motor;
90 
91     Motor *m_motor;
92 
93 };
94 
95 
96 #endif // TCPCLIENT_H 

tcpclient.cpp

  1 #include "tcpclient.h"
  2 #include "ui_tcpclient.h"
  3 #include <QFile>
  4 #include <QDataStream>
  5 
  6 
  7 QDataStream & operator<<(QDataStream &out,const Motor &motor)
  8 {
  9     //qDebug()<< motor.m_speed<<motor.m_p_some<<motor.m_accele_speed<<"Enter in";
 10     out << motor.m_speed<<motor.m_p_some<<motor.m_accele_speed;
 11     //qDebug()<< motor.m_speed<<motor.m_p_some<<motor.m_accele_speed<<"Enter in this";
 12     return out;
 13 }
 14 
 15 QDataStream &operator >>(QDataStream &in,Motor &motor)
 16 {
 17     int speed = 0;
 18     int accele_speed =0;
 19     int p_some = 0;
 20 
 21     in >> speed >> p_some >> accele_speed;
 22 
 23     motor.setV(speed);
 24     motor.setP(p_some);
 25     motor.setA(accele_speed);
 26 
 27     return in;
 28 }
 29 Q_DECLARE_METATYPE(Motor)
 30 
 31 
 32 TcpClient::TcpClient(QWidget *parent) :
 33     QMainWindow(parent),
 34     ui(new Ui::TcpClient)
 35 {
 36     ui->setupUi(this);
 37 
 38     qRegisterMetaType<Motor>("Motor");
 39 
 40     tcpClient = new QTcpSocket(this);
 41     connect(ui->Connect_Btn,SIGNAL(clicked()),this,SLOT(slotConnect()));
 42     connect(ui->Send_Btn,SIGNAL(clicked()),this,SLOT(sendMessage()));
 43     connect(tcpClient, SIGNAL(readyRead()), this, SLOT(readMessage()));
 44     connect(tcpClient, SIGNAL(error(QAbstractSocket::SocketError)), this,
 45                 SLOT(displayError(QAbstractSocket::SocketError)));
 46 }
 47 
 48 TcpClient::~TcpClient()
 49 {
 50     delete ui;
 51 }
 52 
 53 void TcpClient::slotConnect()
 54 {
 55     //QString stringAddress = ui->ldt_IP->text();
 56     //QString stringPort = ui->ldt_Port->text();
 57     QString stringAddress = "192.168.154.128";
 58     QString stringPort = "8080";
 59     int port = stringPort.toInt();
 60     QHostAddress address;
 61     address.setAddress(stringAddress);
 62     tcpClient->abort();
 63     tcpClient->connectToHost(address,port);
 64     ui->Connect_Btn->setEnabled(false);
 65 }
 66 
 67 void TcpClient::readMessage()
 68 {
 69 
 70 }
 71 
 72 void TcpClient::displayError(QAbstractSocket::SocketError)
 73 {
 74    qDebug() << tcpClient->errorString();
 75 }
 76 
 77 void TcpClient::sendMessage()
 78 {
 79     QString stringMotor = ui->ldt_Motor->text();
 80     QString stringData = ui->ldt_data->text();
 81     control_Motor.command = stringMotor.toInt();
 82     int dataLength = stringData.length();
 83     control_Motor.length = 8 + dataLength;
 84     control_Motor.data = stringData;
 85     QString data = stringMotor+stringData;
 86 
 87     m_motor = new Motor(20,40,60);
 88 
 89     //Motor m_motor(20,40,60);
 90 
 91     //用于暫存要發送的數據
 92     QByteArray block;
 93     //使用數據流寫入數據
 94     QDataStream out(&block,QIODevice::WriteOnly);
 95     //設置數據流的版本,客戶端和服務器端使用的版本要相同
 96     out.setVersion(QDataStream::Qt_4_6);
 97     out<<(quint32) 0;
 98     //設置發送長度初始值為0
 99     //out << control_Motor.length<<control_Motor.command<<control_Motor.data;
100 
101     //qDebug() << control_Motor.length<<control_Motor.command<<control_Motor.data;
102     //out
103     out << control_Motor.command;
104     qDebug()<<"Start out"<<endl;
105     out << *m_motor;
106     qDebug()<<"End out"<<endl;
107     qDebug() << control_Motor.command<< m_motor->getA()<<m_motor->getP()<<m_motor->getV();
108     //回到字節流起始位置
109     out.device()->seek(0);
110     //重置字節流長度
111     //out << (quint16) (block.size()-sizeof(quint16));
112     out << (quint32)(block.size()- sizeof(quint32));
113     qDebug() << "block.size()"<<block.size();
114 
115     //往套接字緩存中寫入數據,并發送
116     tcpClient->write(block,block.size());
117     tcpClient->disconnectFromHost();
118     tcpClient->waitForDisconnected();
119 
120     block.resize(0);
121     this->close();
122     //tcpClient->write(data.toLatin1(),data.size());
123 }

?

服務器端:

tcpserver.h

 1 ifndef TCPSERVER_H
 2 #define TCPSERVER_H
 3 
 4 #include <QMainWindow>
 5 #include <qt4/Qt/qhostinfo.h>
 6 #include "server.h"
 7 
 8 
 9 namespace Ui {
10 class TcpServer;
11 }
12 
13 class TcpServer : public QMainWindow
14 {
15     Q_OBJECT
16 
17 public:
18     explicit TcpServer(QWidget *parent = 0);
19     ~TcpServer();
20 
21 private:
22     Ui::TcpServer *ui;
23     int port;
24     Server *server;
25 
26 protected slots:
27     void slotCreateServer();
28     void updateServer(QString,int);
29 
30 };
31 
32 #endif // TCPSERVER_H

?

tcpserver.cpp

 1 #include "tcpserver.h"
 2 #include "ui_tcpserver.h"
 3 #include <QtNetwork/QNetworkInterface>
 4 
 5 TcpServer::TcpServer(QWidget *parent) :
 6     QMainWindow(parent),
 7     ui(new Ui::TcpServer)
 8 {
 9     ui->setupUi(this);
10     port = 8080;
11     QString address = QNetworkInterface::allAddresses().first().toString();
12     QList<QHostAddress> list2 = QNetworkInterface::allAddresses();
13     foreach (QHostAddress address, list2)
14     {
15         if(address.protocol() == QAbstractSocket::IPv4Protocol)
16             ui->ldt_IP->setText(address.toString());
17     }
18     ui->ldt_Port->setText(QString::number(port));
19     connect(ui->Connect_Btn,SIGNAL(clicked()),this,SLOT(slotCreateServer()));
20 }
21 
22 TcpServer::~TcpServer()
23 {
24     delete ui;
25 }
26 
27 void TcpServer::slotCreateServer()
28 {
29     server = new Server(this,port);
30     connect(server,SIGNAL(updateServer(QString,int)),this,SLOT(updateServer(QString,int)));
31     ui->Connect_Btn->setEnabled(false);
32 }
33 
34 void TcpServer::updateServer(QString msg, int length)
35 {
36     ui->lwt_Text->addItem(msg.left(length));
37 }

?

server.h

 1 #ifndef SERVER_H
 2 #define SERVER_H
 3 
 4 #include <qt4/Qt/qtcpserver.h>
 5 #include <qt4/Qt/qtcpsocket.h>
 6 
 7 struct Control_Motor
 8 {
 9     int length;
10     int command;
11     QString data;
12 };
13 
14 
15 class Motor
16 {
17 public:
18     Motor(int speed,int accele_speed,int p_some)
19     {
20         m_speed = speed;
21         m_accele_speed = accele_speed;
22         m_p_some = p_some;
23     }
24 
25     Motor(){m_speed = 0;}
26 
27 
28 
29 public:
30     int getV(){return m_speed;}
31     int getA(){return m_accele_speed;}
32     int getP(){return m_p_some;}
33 
34     void setV(const int v){m_speed = v;}
35     void setA(const int a){m_accele_speed = a;}
36     void setP(const int p){m_p_some = p;}
37 
38 
39 
40 private:
41     int m_speed;
42     int m_accele_speed;
43     int m_p_some;
44 
45 };
46 
47 
48 
49 class Server : public QTcpServer
50 {
51     Q_OBJECT
52 
53 public:
54     Server(QObject *parents=0,int port=0);
55     QList<QTcpSocket*>TcpClientSocketList;
56     QTcpSocket *tcpClientSocket;
57 signals:
58     void updateServer(QString,int);
59 
60 public slots:
61     void slotUpdateClient(QString,int);
62     void slotDisconnect(int);
63 //    void slotnewconnection();
64 protected:
65     void incomingConnection(int socketDescriptor);
66 
67 signals:
68     void updateClients(QString,int);
69     void disconnected(int);
70 
71 protected slots:
72     void dataReceive();
73     void slotDisconnected();
74 
75 public:
76     Control_Motor control_motor;
77     Motor m_mtor;
78 };
79 
80 #endif // SERVER_H

?

server.cpp

  1 #include "server.h"
  2 
  3 QDataStream &operator <<(QDataStream &out,Motor &motor)
  4 {
  5     out << motor.getV()<<motor.getP()<<motor.getA();
  6     return out;
  7 }
  8 
  9 
 10 QDataStream &operator >>(QDataStream &in,Motor &motor)
 11 {
 12     int speed = motor.getV();
 13     int accele_speed =motor.getA();
 14     int p_some = motor.getP();
 15 
 16     in >> speed >> p_some >> accele_speed;
 17 
 18     motor.setV(speed);
 19     motor.setP(p_some);
 20     motor.setA(accele_speed);
 21 
 22     return in;
 23 }
 24 
 25 
 26 
 27 
 28 Server::Server(QObject *parent,int port) :
 29     QTcpServer(parent)
 30 {
 31     this->listen(QHostAddress::Any,port);
 32 }
 33 
 34 void Server::incomingConnection(int socketDescriptor)
 35 {
 36     tcpClientSocket = new QTcpSocket(this);
 37     //tcpClientSocket = this->nextPendingConnection();
 38     tcpClientSocket->setSocketDescriptor(socketDescriptor);
 39     TcpClientSocketList.append(tcpClientSocket);
 40     //connect(this,SIGNAL(updateClients(QString,int)),this,SLOT(slotUpdateClient(QString,int)));
 41     //connect(this,SIGNAL(updateClients(QString,int)),this,SLOT(slotUpdateClient(QString,int)));
 42     connect(this,SIGNAL(disconnected(int)),this,SLOT(slotDisconnect(int)));
 43     connect(tcpClientSocket,SIGNAL(readyRead()),this,SLOT(dataReceive()));
 44     connect(tcpClientSocket,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));
 45     //connect(tcpClientSocket,SIGNAL(disconnected()),tcpClientSocket,SLOT(deleteLater()));
 46 
 47 }
 48 void Server::slotUpdateClient(QString msg,int length)
 49 {
 50     emit updateServer(msg,length);
 51     for (int i=0;i<TcpClientSocketList.count();i++)
 52     {
 53         QTcpSocket *item=TcpClientSocketList.at(i);
 54         if (item->write(msg.toLatin1(),length)!=length)
 55             continue;
 56     }
 57 }
 58 void Server::slotDisconnect(int socketDescriptor)
 59 {
 60     qDebug()<<__FILE__<<__FUNCTION__<<__LINE__<<endl;
 61     for (int i=0;i<TcpClientSocketList.count();i++)
 62      if (TcpClientSocketList.at(i)->socketDescriptor()==socketDescriptor)
 63      {
 64            TcpClientSocketList.removeAt(i);
 65             return;
 66      }
 67 }
 68 
 69 void Server::dataReceive()
 70 {
 71     qDebug()<<"QQWQW11111111111111";
 72     //quint32 size = 0;
 73     quint32 nextBlockSize = 0;
 74     qDebug()<<"TcpClientSocketList.count()"<<TcpClientSocketList.count();
 75     //for(int i = 0; i < TcpClientSocketList.count();i++)
 76     //{
 77         QDataStream in(tcpClientSocket);
 78         in.setVersion(QDataStream::Qt_4_6);
 79        if(nextBlockSize == 0)
 80        {
 81            if(tcpClientSocket->bytesAvailable()<sizeof(quint32))
 82            {
 83                //break;
 84                return;
 85            }
 86            in>>nextBlockSize;
 87            qDebug()<<nextBlockSize;
 88        }
 89        if(nextBlockSize==0xFFFF)
 90        {
 91            //break;
 92            return;
 93        }
 94        if(tcpClientSocket->bytesAvailable()<nextBlockSize)
 95        {
 96            //break;
 97            return;
 98        }
 99 
100        //in>>control_motor.length>>control_motor.command>>control_motor.data;
101 
102        //qDebug()<<control_motor.length<<control_motor.command<<control_motor.data;
103        in >>control_motor.command >> m_mtor;
104        qDebug()<<control_motor.command<< m_mtor.getA()<<m_mtor.getP()<<m_mtor.getV();
105 
106        //ui->SN_lineEdit_2->setText(QString("%1").arg(message_rev.SN));
107        //ui->IP_lineEdit->setText(message_rev.IP);
108        //ui->STATE_lineEdit_3->setText(message_rev.Condition);
109     //}
110 }
111 
112 void Server::slotDisconnected()
113 {
114     qDebug()<<__FILE__<<__FUNCTION__<<__LINE__<<endl;
115     emit disconnected(tcpClientSocket->socketDescriptor());
116 }

?

?

在這里要特別說明一下,在此遇到的幾個問題,希望能幫到大家,也提醒一下自己。

1.在TcpClient.pro,TcpServer.pro里一定要注意加上QT += network,不然編譯的時候QNetworkInterface、QHostAddress這些地方會報錯誤。

2.在QDataStream重載自定義的類的時候,一開始把重載寫在.h文件里編譯的時候總是報Tcp_DataStream/TcpServer/server.h:49: error: multiple definition of `operator<<(QDataStream&, Motor&)'這個錯誤,說實話這個問題真的困擾了我很久,然后把重載函數放到.cpp文件里,編譯通過,簡直是要命

3.QDataStream的nextBlock讀取到的長度為發送的數據的長度(而不是整個包的長度out << (quint32)(block.size()- sizeof(quint32));),如果直接寫out << (quint32)(block.size()),讀的時候數據將會不正常。

4.重載的時候一定要正確。

?

轉載于:https://www.cnblogs.com/wanzaiyimeng/p/4572074.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/375880.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/375880.shtml
英文地址,請注明出處:http://en.pswp.cn/news/375880.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

android mina分析,Android與Mina整合

最近想在自己做的安卓手機應用中加入即時聊天功能&#xff0c;于是想到了用Mina來實現&#xff0c;也是由于自己想著偷懶&#xff0c;借用了官方的example中chat的相關代碼&#xff0c;經過一番改造&#xff0c;很快就能在java環境中正常運行了。確認沒問題后&#xff0c;將cli…

棧的應用--括號匹配的檢驗

算法中設置一個棧&#xff0c;每次讀入一個括號&#xff0c;若是右括號&#xff0c;則或者與置于棧頂的括號匹配&#xff0c;或者是不合法的情況&#xff0c;若是左括號&#xff0c;則入棧。若算法結束&#xff0c;棧是空的&#xff0c;則括號合法。 括號匹配函數 Status bra…

node.js 初體驗

node.js 初體驗 2011-10-31 22:56 by 聶微東, 174545 閱讀, 118 評論, 收藏, 編輯 PS: ~ 此篇文章的進階內容在為《Nodejs初階之express》 ~ 2014/09/24 更新《Express 4.X 啟航指南》 歡迎閱讀和評論:) 最近寫的文章收到許多朋友的反饋&#xff0c;感謝大家的支持和建議&#…

Qt之模型/視圖(實時更新數據)

上兩節簡單介紹了Qt中對于模型/視圖的編程&#xff0c;大部分助手里說的很清楚了&#xff0c;現在就開始實戰部分吧&#xff01; 在實際應用中&#xff0c;視圖展示的數據往往并非一成不變的&#xff0c;那么如何實時更新成了一個很重要的問題&#xff01;功能&#xff1a;&am…

android 動態生成fragment,Android動態加載fragment(fragment復用)

【實例簡介】Android動態加載fragment(fragment復用)【實例截圖】【核心代碼】fm_reuse└── fm_reuse├── AndroidManifest.xml├── bin│ ├── AndroidManifest.xml│ ├── classes│ │ └── com│ │ └── example│ │ └── fm_reuse│ …

Linux內核3.0移植并基于Initramfs根文件系統啟動

Linux內核移植與啟動 Target borad&#xff1a;FL2440 Bootloader&#xff1a;U-boot-2010.09 交叉編譯器&#xff1a;buildroot-2012.08 1.linux內核基礎知識 首先&#xff0c;磨刀不誤砍柴工。在動手進行linux內核移植之前&#xff0c;我們有必要對linux內核進行一定的了解。…

操作系統上機作業--實現shell(2)(多進程)

sh2.c: 實現shell程序&#xff0c;要求在第1版的基礎上&#xff0c;添加如下功能 ? 實現文件重定向 ? $ echo hello >log ? $ cat log ? Hello 實現思路&#xff1a; 和sh1.c相比&#xff0c;主要是修改了cmd函數的實現過程。通過循環找出重定向符號"&g…

當泛型方法推斷,擴展方法遇到泛型類型in/out時。。。

說到泛型方法&#xff0c;這個是.net 2.0的時候引入的一個重要功能&#xff0c;c#2.0也對此作了非常好的支持&#xff0c;可以不需要顯試的聲明泛型類型&#xff0c;讓編譯器自動推斷&#xff0c;例如&#xff1a; 1 void F<T>(T value){} 2 //... 3 int i 0; 4 F(i); 此…

AOP相關

實現AOP的技術&#xff0c;主要分為兩大類&#xff1a;一是采用動態代理技術&#xff0c;利用截取消息的方式&#xff0c;對該消息進行裝飾&#xff0c;以取代原有對象行為的執行&#xff1b;二是采用靜態織入的方式&#xff0c;引入特定的語法創建“方面”&#xff0c;從而使得…

操作系統上機作業--根據萊布尼茲級數計算PI(1)(多線程)

pi1.c: 使用2個線程根據萊布尼茲級數計算PI ? 萊布尼茲級數公式: 1 - 1/3 1/5 - 1/7 1/9 - ... PI/4 ? 主線程創建1個輔助線程 ? 主線程計算級數的前半部分 ? 輔助線程計算級數的后半部分 ? 主線程等待輔助線程運行結束后,將前半部分和后半部分相加實現思路&#xff1…

四種途徑將HTML5 web應用變成android應用

作為下一代的網頁語言&#xff0c;HTML5擁有很多讓人期待已久的新特性。HTML5的優勢之一在于能夠實現跨平臺游戲編碼移植&#xff0c;現在已經有很多公司在移動設備上使用HTML5技術。隨著HTML5跨平臺支持的不斷增強和智能手機的迅速普&#xff0c;HTML5技術有著非常好的發展前景…

操作系統上機作業--根據萊布尼茲級數計算PI(2)(多線程)

pi2.c: 使用N個線程根據萊布尼茲級數計算PI ? 與上一題類似&#xff0c;但本題更加通用化&#xff0c;能適應N個核心&#xff0c;需要使用線程參數來實現 ? 主線程創建N個輔助線程 ? 每個輔助線程計算一部分任務&#xff0c;并將結果返回 ? 主線程等待N個輔助線程…

html 16進制 轉換成字符串,js 字符串和16進制的互相轉換

字符串轉16進制function strToHexCharCode(str) {if(str "")return "";var hexCharCode [];hexCharCode.push("0x");for(var i 0; i < str.length; i) {hexCharCode.push((str.charCodeAt(i)).toString(16));}return hexCharCode.join(&qu…

數組以及冒泡排序

數組 1、概念&#xff1a;可以幫我一次聲明多個同類型的變量&#xff0c;這些變量再內存中是連續存儲的。 2、聲明語法&#xff1a;數據類型[] 數組名 new 數據類型[數組長度] 數組長度&#xff1a;一次要聲明的同類型的變量個數。是在定義這個數組的時候就確定了&#xf…

jQuery觸發a標簽的點擊事件無效

1 <a id"workFrame" href"pages/work.html" target"FrameBox">首頁</a> 2 3 $("#workFrame").tigger("click"); 上述的代碼&#xff0c;其實挺正常的&#xff0c;但是怎么也觸發不了a標簽的cli…

操作系統上機作業--多線程排序

sort.c: 多線程排序 ? 主線程創建一個輔助線程 ? 主線程使用選擇排序算法對數組的前半部分排序 ? 輔助線程使用選擇排序算法對數組的后半部分排序 ? 主線程等待輔助線程運行結束后,使用歸并排序算法歸并數組的前半部分和后半部分 實現思路&#xff1a; ARRAY_CO…

jdk5下載鏈接

查看jdk版本 java -versionJDK下載 最新版本http://www.oracle.com/technetwork/java/javase/downloads/index.htmlJDK下載 版本1.5.22http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase5-419410.html#jdk-1.5.0_22-oth-JPR JDK…

html的細節優化,網站頁面優化細節詳解

原標題&#xff1a;網站頁面優化細節詳解SEO頁面優化是繼SEO結構優化之后&#xff0c;另一個重要優化地方;頁面標題在每個頁面中的關鍵位置&#xff0c;出現目標關鍵詞&#xff0c;這是我們做頁面優化的基礎思路&#xff0c;關鍵詞位置&#xff0c;都有哪些呢?第一個是關鍵位置…

突擊優化算法!

Matlab語言可以與C/C語言轉換或調用。 Matlab語句&#xff1a;load name 把name中文件的所有變量載入到工作空間中。save name 保存工作空間的變量到name.mat中。 cholesky分解把一個正定矩陣分為一個下三角矩陣和它轉置矩陣的乘積。 兩種創立符號函數的方法&#xff1a;sym函數…

操作系統上機作業--使用條件變量解決生產者、計算者、消費者問題(多線程)

pc1.c: 使用條件變量解決生產者、計算者、消費者問題 /* ? 系統中有3個線程&#xff1a;生產者、計算者、消費者 ? 系統中有2個容量為4的緩沖區&#xff1a;buffer1、buffer2 ? 生產者生產a、b、c、‘d、e、f、g、h八個字符&#xff0c;放入到buffer1 ? 計算者從b…