嵌入式学习——虚拟机通信

打印 上一主题 下一主题

主题 2014|帖子 2014|积分 6042

目次

虚拟机talk通信
自主编程实现通信(1)
自主编程实现通信(2)


虚拟机talk通信

如果我们想在虚拟机上与其他同学或朋侪取得接洽,我们可以使用talk程序举行交流。首先我们要打开虚拟机,执行以下下令,安装talk程序;
   sudo apt update
  sudo apt installbsd-talk
  

然后使用下令启动程序;
   sudo systemctl start talk
  sudo ufw allow talk
  接着我们就可以使用下令举行通信;
   talk fangjq
  (这里talk 后面接上你想要通信的用户)
  


这里要注意输入内容以及一些快捷键,否则会出现一些问题;例如^Z是使用了CTRL快捷键,回复的Hello后面的问号是输入问题。
自主编程实现通信(1)

在同一终端下,子进程与父进程的通信;
首先创建一个目次:chat_program用来存放我们的相关文件
   mkdir chat_program //创建目次
  cd chat_program //进入目次
  nano chat.c //创建文件
  然后粘贴以下的代码,
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/select.h>
  6. #define BUFFER_SIZE 1024
  7. #define EXIT_CMD "exit"
  8. int main() {
  9.     int pipefd[2]; // 父进程到子进程的管道
  10.     int pipefd2[2]; // 子进程到父进程的管道
  11.     pid_t pid;
  12.     // 创建两个管道
  13.     if (pipe(pipefd) == -1 || pipe(pipefd2) == -1) {
  14.         perror("pipe");
  15.         exit(EXIT_FAILURE);
  16.     }
  17.     // 创建子进程
  18.     pid = fork();
  19.     if (pid == -1) {
  20.         perror("fork");
  21.         exit(EXIT_FAILURE);
  22.     }
  23.     if (pid == 0) {
  24.         // 子进程:从父进程接收消息并通过另一个管道发送消息
  25.         close(pipefd[1]); // 关闭写端
  26.         close(pipefd2[0]); // 关闭读端
  27.         char buffer[BUFFER_SIZE];
  28.         fd_set readfds;
  29.         int max_fd = (pipefd[0] > pipefd2[1]) ? pipefd[0] : pipefd2[1];
  30.         while (1) {
  31.             FD_ZERO(&readfds);
  32.             FD_SET(STDIN_FILENO, &readfds);
  33.             FD_SET(pipefd[0], &readfds);
  34.             if (select(max_fd + 1, &readfds, NULL, NULL, NULL) == -1) {
  35.                 perror("select");
  36.                 exit(EXIT_FAILURE);
  37.             }
  38.             if (FD_ISSET(STDIN_FILENO, &readfds)) {
  39.                 // 从标准输入读取消息并发送给父进程
  40.                 ssize_t bytes_read = read(STDIN_FILENO, buffer, BUFFER_SIZE);
  41.                 if (bytes_read <= 0) {
  42.                     break;
  43.                 }
  44.                 buffer[bytes_read - 1] = '\0'; // 去掉换行符
  45.                 if (strcmp(buffer, EXIT_CMD) == 0) {
  46.                     write(pipefd2[1], buffer, strlen(buffer) + 1);
  47.                     break;
  48.                 }
  49.                 write(pipefd2[1], buffer, strlen(buffer) + 1);
  50.             }
  51.             if (FD_ISSET(pipefd[0], &readfds)) {
  52.                 // 从父进程接收消息并输出
  53.                 ssize_t bytes_read = read(pipefd[0], buffer, BUFFER_SIZE);
  54.                 if (bytes_read <= 0) {
  55.                     break;
  56.                 }
  57.                 buffer[bytes_read] = '\0';
  58.                 printf("Parent: %s\n", buffer);
  59.                 if (strcmp(buffer, EXIT_CMD) == 0) {
  60.                     break;
  61.                 }
  62.             }
  63.         }
  64.         close(pipefd[0]);
  65.         close(pipefd2[1]);
  66.         exit(EXIT_SUCCESS);
  67.     } else {
  68.         // 父进程:从子进程接收消息并通过另一个管道发送消息
  69.         close(pipefd[0]); // 关闭读端
  70.         close(pipefd2[1]); // 关闭写端
  71.         char buffer[BUFFER_SIZE];
  72.         fd_set readfds;
  73.         int max_fd = (pipefd2[0] > pipefd[1]) ? pipefd2[0] : pipefd[1];
  74.         while (1) {
  75.             FD_ZERO(&readfds);
  76.             FD_SET(STDIN_FILENO, &readfds);
  77.             FD_SET(pipefd2[0], &readfds);
  78.             if (select(max_fd + 1, &readfds, NULL, NULL, NULL) == -1) {
  79.                 perror("select");
  80.                 exit(EXIT_FAILURE);
  81.             }
  82.             if (FD_ISSET(STDIN_FILENO, &readfds)) {
  83.                 // 从标准输入读取消息并发送给子进程
  84.                 ssize_t bytes_read = read(STDIN_FILENO, buffer, BUFFER_SIZE);
  85.                 if (bytes_read <= 0) {
  86.                     break;
  87.                 }
  88.                 buffer[bytes_read - 1] = '\0'; // 去掉换行符
  89.                 if (strcmp(buffer, EXIT_CMD) == 0) {
  90.                     write(pipefd[1], buffer, strlen(buffer) + 1);
  91.                     break;
  92.                 }
  93.                 write(pipefd[1], buffer, strlen(buffer) + 1);
  94.             }
  95.             if (FD_ISSET(pipefd2[0], &readfds)) {
  96.                 // 从子进程接收消息并输出
  97.                 ssize_t bytes_read = read(pipefd2[0], buffer, BUFFER_SIZE);
  98.                 if (bytes_read <= 0) {
  99.                     break;
  100.                 }
  101.                 buffer[bytes_read] = '\0';
  102.                 printf("Child: %s\n", buffer);
  103.                 if (strcmp(buffer, EXIT_CMD) == 0) {
  104.                     break;
  105.                 }
  106.             }
  107.         }
  108.         close(pipefd[1]);
  109.         close(pipefd2[0]);
  110.         wait(NULL); // 等待子进程结束
  111.     }
  112.     return 0;
  113. }
复制代码

随后通过gcc编译器编译一遍,接着运行,尝试通信;
   gcc chat.c -o chat
  ./chat
  

完成过后可以通过CTRL+C退出程序。在这段程序中,使用两个进程相互通信,首先根据用户输入的内容,子进程接收过后输出,发出第一段对话,然后用户再输入,接着父进程接收并输出,完成对子进程的回应,这段代码是子进程与父进程轮流对话,机动性较低,不能多段输出,只能轮回。
除了这种,还有两个终端的对话。

自主编程实现通信(2)

在同一个账号两个终端之间通信;
这里建议先使用IPC或消息管道、消息槽等模式,然后举行实践。
使用以下下令创建管道文件,
   mkfifo mypipe
  在虚拟机中,管道文件(通常指命名管道或 FIFO 文件)是一种进程间通信(IPC)机制,用于在虚拟机内部或虚拟机与主机之间传递数据。通过创建命名管道文件(如 mkfifo 下令),虚拟机内部的进程可以实现通信。
首先创建两个文件,sender.c和receiver.c,然后输入以下代码;
   nano sender.c
  nano receive.c
  sender.c:
  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <unistd.h>
  4.  
  5. int main() {
  6.     int fd = open("mypipe", O_WRONLY);
  7.     if (fd == -1) {
  8.         perror("open");
  9.         return 1;
  10.     }
  11.  
  12.     char buffer[100];
  13.     printf("Enter message: ");
  14.     fgets(buffer, sizeof(buffer), stdin);
  15.     write(fd, buffer, strlen(buffer)+1);
  16.     close(fd);
  17.     return 0;
  18. }
复制代码
receiver.c:
  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <unistd.h>
  4.  
  5. int main() {
  6.     int fd = open("mypipe", O_RDONLY);
  7.     if (fd == -1) {
  8.         perror("open");
  9.         return 1;
  10.     }
  11.  
  12.     char buffer[100];
  13.     read(fd, buffer, sizeof(buffer));
  14.     printf("Received message: %s", buffer);
  15.     close(fd);
  16.     return 0;
  17. }
复制代码
同样的操作举行编译,编译过后终端一运行sender.c,终端二运行receive.c,测试运行结果。


可以看到,发送hello,也能接收到hello,这个程序的问题在于只能一条一条发送,而且单项发送。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

守听

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表