嵌入式学习——虚拟机通信
目次虚拟机talk通信
自主编程实现通信(1)
自主编程实现通信(2)
虚拟机talk通信
如果我们想在虚拟机上与其他同学或朋侪取得接洽,我们可以使用talk程序举行交流。首先我们要打开虚拟机,执行以下下令,安装talk程序;
sudo apt update
sudo apt installbsd-talk
https://i-blog.csdnimg.cn/direct/c7a40dc1924949af8b53c5ed0fdc0895.png
然后使用下令启动程序;
sudo systemctl start talk
sudo ufw allow talk
接着我们就可以使用下令举行通信;
talk fangjq
(这里talk 后面接上你想要通信的用户)
https://i-blog.csdnimg.cn/direct/8490834644e44febb2f16ed5db6ba6db.png
https://i-blog.csdnimg.cn/direct/57be8f5a25d44de4b2cad719e7189337.png
这里要注意输入内容以及一些快捷键,否则会出现一些问题;例如^Z是使用了CTRL快捷键,回复的Hello后面的问号是输入问题。
自主编程实现通信(1)
在同一终端下,子进程与父进程的通信;
首先创建一个目次:chat_program用来存放我们的相关文件
mkdir chat_program //创建目次
cd chat_program //进入目次
nano chat.c //创建文件
然后粘贴以下的代码,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#define BUFFER_SIZE 1024
#define EXIT_CMD "exit"
int main() {
int pipefd; // 父进程到子进程的管道
int pipefd2; // 子进程到父进程的管道
pid_t pid;
// 创建两个管道
if (pipe(pipefd) == -1 || pipe(pipefd2) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
// 创建子进程
pid = fork();
if (pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0) {
// 子进程:从父进程接收消息并通过另一个管道发送消息
close(pipefd); // 关闭写端
close(pipefd2); // 关闭读端
char buffer;
fd_set readfds;
int max_fd = (pipefd > pipefd2) ? pipefd : pipefd2;
while (1) {
FD_ZERO(&readfds);
FD_SET(STDIN_FILENO, &readfds);
FD_SET(pipefd, &readfds);
if (select(max_fd + 1, &readfds, NULL, NULL, NULL) == -1) {
perror("select");
exit(EXIT_FAILURE);
}
if (FD_ISSET(STDIN_FILENO, &readfds)) {
// 从标准输入读取消息并发送给父进程
ssize_t bytes_read = read(STDIN_FILENO, buffer, BUFFER_SIZE);
if (bytes_read <= 0) {
break;
}
buffer = '\0'; // 去掉换行符
if (strcmp(buffer, EXIT_CMD) == 0) {
write(pipefd2, buffer, strlen(buffer) + 1);
break;
}
write(pipefd2, buffer, strlen(buffer) + 1);
}
if (FD_ISSET(pipefd, &readfds)) {
// 从父进程接收消息并输出
ssize_t bytes_read = read(pipefd, buffer, BUFFER_SIZE);
if (bytes_read <= 0) {
break;
}
buffer = '\0';
printf("Parent: %s\n", buffer);
if (strcmp(buffer, EXIT_CMD) == 0) {
break;
}
}
}
close(pipefd);
close(pipefd2);
exit(EXIT_SUCCESS);
} else {
// 父进程:从子进程接收消息并通过另一个管道发送消息
close(pipefd); // 关闭读端
close(pipefd2); // 关闭写端
char buffer;
fd_set readfds;
int max_fd = (pipefd2 > pipefd) ? pipefd2 : pipefd;
while (1) {
FD_ZERO(&readfds);
FD_SET(STDIN_FILENO, &readfds);
FD_SET(pipefd2, &readfds);
if (select(max_fd + 1, &readfds, NULL, NULL, NULL) == -1) {
perror("select");
exit(EXIT_FAILURE);
}
if (FD_ISSET(STDIN_FILENO, &readfds)) {
// 从标准输入读取消息并发送给子进程
ssize_t bytes_read = read(STDIN_FILENO, buffer, BUFFER_SIZE);
if (bytes_read <= 0) {
break;
}
buffer = '\0'; // 去掉换行符
if (strcmp(buffer, EXIT_CMD) == 0) {
write(pipefd, buffer, strlen(buffer) + 1);
break;
}
write(pipefd, buffer, strlen(buffer) + 1);
}
if (FD_ISSET(pipefd2, &readfds)) {
// 从子进程接收消息并输出
ssize_t bytes_read = read(pipefd2, buffer, BUFFER_SIZE);
if (bytes_read <= 0) {
break;
}
buffer = '\0';
printf("Child: %s\n", buffer);
if (strcmp(buffer, EXIT_CMD) == 0) {
break;
}
}
}
close(pipefd);
close(pipefd2);
wait(NULL); // 等待子进程结束
}
return 0;
}
随后通过gcc编译器编译一遍,接着运行,尝试通信;
gcc chat.c -o chat
./chat
https://i-blog.csdnimg.cn/direct/408cee43a17640cea642735b843dcdf6.png
完成过后可以通过CTRL+C退出程序。在这段程序中,使用两个进程相互通信,首先根据用户输入的内容,子进程接收过后输出,发出第一段对话,然后用户再输入,接着父进程接收并输出,完成对子进程的回应,这段代码是子进程与父进程轮流对话,机动性较低,不能多段输出,只能轮回。
除了这种,还有两个终端的对话。
自主编程实现通信(2)
在同一个账号两个终端之间通信;
这里建议先使用IPC或消息管道、消息槽等模式,然后举行实践。
使用以下下令创建管道文件,
mkfifo mypipe
在虚拟机中,管道文件(通常指命名管道或 FIFO 文件)是一种进程间通信(IPC)机制,用于在虚拟机内部或虚拟机与主机之间传递数据。通过创建命名管道文件(如 mkfifo 下令),虚拟机内部的进程可以实现通信。
首先创建两个文件,sender.c和receiver.c,然后输入以下代码;
nano sender.c
nano receive.c
sender.c:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("mypipe", O_WRONLY);
if (fd == -1) {
perror("open");
return 1;
}
char buffer;
printf("Enter message: ");
fgets(buffer, sizeof(buffer), stdin);
write(fd, buffer, strlen(buffer)+1);
close(fd);
return 0;
} receiver.c:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("mypipe", O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
char buffer;
read(fd, buffer, sizeof(buffer));
printf("Received message: %s", buffer);
close(fd);
return 0;
} 同样的操作举行编译,编译过后终端一运行sender.c,终端二运行receive.c,测试运行结果。
https://i-blog.csdnimg.cn/direct/22022237cb9c4047bbf666e13bef7148.png
https://i-blog.csdnimg.cn/direct/f1cb5ede26664ca88722bb56d741601c.png
可以看到,发送hello,也能接收到hello,这个程序的问题在于只能一条一条发送,而且单项发送。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]