寒假(一)

請使用消息隊列實現2個終端之間互相聊天

終端一

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/msg.h>#define MSG_SIZE 64
#define MSG_TYPE_1 1
#define MSG_TYPE_2 2typedef struct {long change;       // 消息類型(頻道)char dup[MSG_SIZE]; // 消息內容
} msg_data;key_t key;      // 消息隊列的鍵值
int msg_id;     // 消息隊列的ID// 信號處理函數
void handler(int signum) {if (signum == SIGINT) {printf("\n程序退出,銷毀消息隊列...\n");msgctl(msg_id, IPC_RMID, NULL); // 銷毀消息隊列exit(0);}
}// 消息寫入函數
void msg_w() {msg_data arr;while (1) {arr.change = MSG_TYPE_1; // 設置消息類型printf("請輸入:");scanf("%s", arr.dup);    // 讀取用戶輸入if (msgsnd(msg_id, &arr, strlen(arr.dup) + 1, 0) == -1) {perror("msgsnd");break;}}
}// 消息讀取函數
void msg_r() {msg_data arr;while (1) {if (msgrcv(msg_id, &arr, sizeof(arr.dup), MSG_TYPE_2, 0) == -1) {perror("msgrcv");break;}printf("\b\b\b\b\b\b\b\b收到的消息為:%s\n", arr.dup);memset(arr.dup, 0, sizeof(arr.dup)); // 清空消息緩沖區}
}// 線程函數
void* pthread_main(void* arg) {msg_w();return NULL;
}// 清理函數
void cleanup() {printf("清理消息隊列...\n");msgctl(msg_id, IPC_RMID, NULL);
}int main(int argc, const char *argv[]) {pthread_t pthread_id;// 注冊信號處理函數signal(SIGINT, handler);// 注冊清理函數atexit(cleanup);// 生成消息隊列的鍵值key = ftok("1.txt", 1);if (key == -1) {perror("ftok");exit(1);}// 創建消息隊列msg_id = msgget(key, IPC_CREAT | 0664);if (msg_id == -1) {perror("msgget");exit(1);}// 創建線程if (pthread_create(&pthread_id, NULL, pthread_main, NULL) != 0) {perror("pthread_create");exit(1);}pthread_detach(pthread_id); // 設置線程為分離狀態// 主線程負責讀取消息msg_r();return 0;
}

終端二

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <signal.h>
#include <pthread.h>#define MSG_TYPE_SEND 1   // 本終端發送的消息類型
#define MSG_TYPE_RECV 2   // 本終端接收的消息類型
#define MSG_BUFFER_SIZE 64
#define KEY_FILE_PATH "msgq_chat.key"
#define PROJECT_ID 12345typedef struct {long mtype;            // 消息類型char mtext[MSG_BUFFER_SIZE]; // 消息內容
} msg_data;static int msg_id = -1;// 信號處理函數:清理消息隊列
void handle_signal(int signum) {if (signum == SIGINT) {printf("\n正在清理消息隊列...\n");if (msg_id != -1) {msgctl(msg_id, IPC_RMID, NULL);}exit(EXIT_SUCCESS);}
}// 消息發送線程函數
void* send_thread(void *arg) {msg_data msg;while (1) {msg.mtype = MSG_TYPE_SEND;printf("[You] > ");if (fgets(msg.mtext, MSG_BUFFER_SIZE, stdin) == NULL) {perror("fgets");break;}// 去除換行符并計算真實長度size_t len = strcspn(msg.mtext, "\n");msg.mtext[len] = '\0';if (msgsnd(msg_id, &msg, len + 1, IPC_NOWAIT) == -1) { // 非阻塞發送perror("消息發送失敗");usleep(100000); // 發送失敗時等待100ms}}return NULL;
}// 消息接收處理
void receive_messages() {msg_data msg;while (1) {ssize_t ret = msgrcv(msg_id, &msg, MSG_BUFFER_SIZE, MSG_TYPE_RECV, 0);if (ret == -1) {perror("消息接收失敗");break;}printf("\r[Other] > %s\n[You] > ", msg.mtext);fflush(stdout); // 確保立即刷新輸出}
}int main() {// 生成唯一Keykey_t key = ftok(KEY_FILE_PATH, PROJECT_ID);if (key == -1) {perror("無法生成消息隊列Key");exit(EXIT_FAILURE);}// 創建/獲取消息隊列msg_id = msgget(key, IPC_CREAT | 0666);if (msg_id == -1) {perror("無法創建消息隊列");exit(EXIT_FAILURE);}// 注冊信號處理signal(SIGINT, handle_signal);// 創建發送線程pthread_t tid;if (pthread_create(&tid, NULL, send_thread, NULL) != 0) {perror("無法創建發送線程");exit(EXIT_FAILURE);}pthread_detach(tid);// 主線程處理接收printf("--- 聊天室已啟動 (Ctrl+C退出) ---\n");receive_messages();return EXIT_SUCCESS;
}

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

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

相關文章

java項目驗證碼登錄

1.依賴 導入hutool工具包用于創建驗證碼 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.5.2</version></dependency> 2.測試 生成一個驗證碼圖片&#xff08;生成的圖片瀏覽器可…

4 前端前置技術(中):node.js環境

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言 前言

BUU14 [極客大挑戰 2019]PHP1

用dirsearch掃描文件&#xff0c;掃了一萬年什么也沒掃出來 從網上看的wp&#xff0c;他們掃出來www.zip 這里直接用上了&#xff0c;以后有空再掃一遍 下載www.zip 在index.php中 說明要輸入select 打開class.php <?php include flag.php;error_reporting(0);class…

7-9 乘法口訣數列

本題要求你從任意給定的兩個 1 位數字 a1? 和 a2? 開始&#xff0c;用乘法口訣生成一個數列 {an?}&#xff0c;規則為從 a1? 開始順次進行&#xff0c;每次將當前數字與后面一個數字相乘&#xff0c;將結果貼在數列末尾。如果結果不是 1 位數&#xff0c;則其每一位都應成為…

20250202在Ubuntu22.04下使用Guvcview錄像的時候降噪

20250202在Ubuntu22.04下使用Guvcview錄像的時候降噪 2025/2/2 21:25 聲卡&#xff1a;筆記本電腦的攝像頭自帶的【USB接口的】麥克風。沒有外接3.5mm接口的耳機。 緣起&#xff1a;在安裝Ubuntu18.04/20.04系統的筆記本電腦中直接使用Guvcview錄像的時候底噪很大&#xff01; …

使用React和Material-UI構建TODO應用的前端UI

使用React和Material-UI構建TODO應用的前端UI 引言環境準備代碼解析1. 導入必要的模塊2. 創建React組件3. 定義函數3.1 獲取TODO列表3.2 創建TODO項3.3 更新TODO項3.4 刪除TODO項3.5 處理編輯點擊事件3.6 關閉編輯對話框3.7 保存編輯內容 4. 使用Effect鉤子5. 渲染組件 功能實現…

藍橋杯思維訓練營(三)

文章目錄 題目詳解680.驗證回文串 II30.魔塔游戲徒步旅行中的補給問題觀光景點組合得分問題 題目詳解 680.驗證回文串 II 680.驗證回文串 II 思路分析&#xff1a;這個題目的關鍵就是&#xff0c;按照正常來判斷對應位置是否相等&#xff0c;如果不相等&#xff0c;那么就判…

重生之我在異世界學編程之C語言:深入指針篇(上)

大家好&#xff0c;這里是小編的博客頻道 小編的博客&#xff1a;就愛學編程 很高興在CSDN這個大家庭與大家相識&#xff0c;希望能在這里與大家共同進步&#xff0c;共同收獲更好的自己&#xff01;&#xff01;&#xff01; 本文目錄 引言正文&#xff08;1&#xff09;內置數…

密碼學的數學基礎1-素數和RSA加密

數學公式推導是密碼學的基礎, 故開一個新的課題 – 密碼學的數學基礎系列 素數 / 質數 質數又稱素數。 一個大于1的自然數&#xff0c;除了1和它自身外&#xff0c;不能被其他自然數整除的數叫做質數&#xff1b;否則稱為合數&#xff08;規定1既不是質數也不是合數&#xff0…

kamailio源文件modules.lst的內容解釋

在執行make cfg 后&#xff0c;在kamailio/src目錄下有一個文件modules.lst&#xff0c;內容如下&#xff1a; # this file is autogenerated by make modules-cfg# the list of sub-directories with modules modules_dirs:modules# the list of module groups to compile cf…

音視頻入門基礎:RTP專題(7)——RTP協議簡介

一、引言 本文對RTP協議進行簡介。在簡介之前&#xff0c;請各位先下載RTP的官方文檔《RFC 3550》和《RFC 3551》。《RFC 3550》總共有89頁&#xff0c;《RFC 3551》總共有44頁。本文下面所說的“頁數”是指在pdf閱讀器中顯示的頁數&#xff1a; 二、RTP協議簡介 根據《RFC 35…

HTTP協議的無狀態和無連接

無連接 ①無連接的含義 這里所說的無連接并不是指不連接&#xff0c;客戶與服務器之間的HTTP連接是一種一次性連接&#xff0c;它限制每次連接只處理一個請求&#xff0c;當服務器返回本次請求的應答后便立即關閉連接&#xff0c;下次請求再重新建立連接。這種一次性連接主要考…

Java知識速記:Lambda表達式

Java知識速記&#xff1a;Lambda表達式 一、什么是Lambda表達式&#xff1f; Lambda表達式是Java 8引入的一種簡潔的表示函數式接口的方法&#xff0c;它使得可以將函數作為參數傳遞&#xff0c;并且可以在代碼中以更簡潔的方式實現函數式編程。Lambda表達式的基本語法如下&a…

第31章 星騙計劃的推進與團隊協作

我回到自己的辦公室&#xff0c;在座位上剛坐下沒多久&#xff0c;還沒來得及好好整理一下思緒&#xff0c;就聽到一陣敲門聲。“請進。” 我抬頭說道&#xff0c;聲音中帶著一絲疲憊。借助情緒監測系統&#xff0c;我察覺到自己的壓力指數正處于高位&#xff0c;于是暗自提醒自…

半導體器件與物理篇7 微波二極管、量子效應和熱電子器件

基本微波技術 微波頻率&#xff1a;微波頻率涵蓋約從0.1GHz到3000GHz&#xff0c;相當于波長從300cm到0.01cm。 分布效應&#xff1a;電子部件在微波頻率&#xff0c;與其在較低頻率的工作行為不同。 輸運線&#xff1a;一個由電阻、電容、電感三種等效基本電路部件所組成的…

【C++】B2122 單詞翻轉

博客主頁&#xff1a; [小????????] 本文專欄: C 文章目錄 &#x1f4af;前言&#x1f4af;題目描述輸入格式輸出格式樣例 #1樣例輸入 #1樣例輸出 #1 &#x1f4af;一、我的做法代碼實現&#xff1a;代碼解析思路分析 &#x1f4af;二、老師的第一種做法代碼實現&a…

麥芯(MachCore)應用開發教程5 --- 工位和晶圓傳輸

麥芯是構建在windows系統上的設備應用操作系統&#xff0c;利用該系統可以快速高效的開發一款設備專用軟件。希望進一步了解請email: acloud163.com 黃國強 2025/02/03 一、工位與子設備的關系 想象工廠中的流水線工作站&#xff0c;每個工位&#xff08;Station&#xff09…

Python從0到100(八十七):CNN網絡詳細介紹及WISDM數據集模型仿真

前言&#xff1a; 零基礎學Python&#xff1a;Python從0到100最新最全教程。 想做這件事情很久了&#xff0c;這次我更新了自己所寫過的所有博客&#xff0c;匯集成了Python從0到100&#xff0c;共一百節課&#xff0c;幫助大家一個月時間里從零基礎到學習Python基礎語法、Pyth…

C++ Primer 迭代器

歡迎閱讀我的 【CPrimer】專欄 專欄簡介&#xff1a;本專欄主要面向C初學者&#xff0c;解釋C的一些基本概念和基礎語言特性&#xff0c;涉及C標準庫的用法&#xff0c;面向對象特性&#xff0c;泛型特性高級用法。通過使用標準庫中定義的抽象設施&#xff0c;使你更加適應高級…

【C++篇】位圖與布隆過濾器

目錄 一&#xff0c;位圖 1.1&#xff0c;位圖的概念 1.2&#xff0c;位圖的設計與實現 1.5&#xff0c;位圖的應用舉例 1.4&#xff0c;位圖常用應用場景 二&#xff0c;布隆過濾器 2.1&#xff0c;定義&#xff1a; 2.2&#xff0c;布隆過濾器的實現 2.3&#xff0c; 應…