目录
4、配置完后ping一下看看通不通(101是主机,102是虚拟机,103是开发板)
有个注意的地方,如果可以ping通主机,却不能ping通虚拟机,需要查看虚拟机的网络情况,且虚拟机不能联wifi(或关闭主机wifi)。编辑注意看虚拟机的网络设置编辑编辑
1、查看Debian开发板的网络配置
sudo su
cd /etc/networc/
vim interfaces
我的开发板有两个网线插口,分别为eth0和eth1,原来的eth0的配置的自动,我希望是eth0的地址和eth1的地址都由我指定,修改如下:设置为指定的ip,需要设置ip、子网掩码、默认网关。

2、设置电脑的网络
在控制面板找到网络和internet,找到网络和共享中心,点击以太网(如果没有,检查网线是不是已经互相连了)。
点击属性页
设置指定的ip地址,注意,我们开发板设置的ip是192.168.1.103,那电脑只能设置192.168.1.*,*为1~205(除了103),其他两项与开发板设置的要相同。
3、关闭防火墙
电脑的防火墙关闭方法不做过多介绍,注意三个部分都要关闭
以下介绍Debian开发板的防火墙的关闭方法
在 Debian 系统上关闭防火墙通常涉及以下几个步骤。Debian 系统可能使用 ufw
(Uncomplicated Firewall)或 iptables
来管理防火墙规则。以下是如何禁用这些防火墙的步骤:
1. 关闭 ufw
防火墙
如果你的系统使用 ufw
来管理防火墙,可以使用以下命令禁用它,如果没有ufw命令,可以sudo apt-get install ufw去安装一下。
sudo ufw disable
该命令会关闭 ufw
并清除防火墙规则。
2. 关闭 iptables
防火墙
如果你使用 iptables
作为防火墙,禁用防火墙规则的最直接方法是清除所有规则。运行以下命令来清除现有的 iptables
防火墙规则并设置默认的接受策略:
# 清除所有现有规则
sudo iptables -F
# 删除所有自定义链
sudo iptables -X
# 设置默认策略为接受(允许所有流量)
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
3. 禁用 iptables
服务(如果启用)
在一些 Debian 系统上,iptables
可能作为一个服务运行。如果你希望禁用它并确保它在系统重启时不会启动,可以使用以下命令:
# 禁用 iptables 服务
sudo systemctl stop netfilter-persistent
sudo systemctl disable netfilter-persistent
4. 查看防火墙状态
在禁用防火墙之后,你可以运行以下命令来确认防火墙的状态,确保所有规则都已经清除并且允许所有流量:
-
查看
ufw
状态:sudo ufw status
输出应该显示
Status: inactive
,表示ufw
防火墙已被禁用。 -
查看
iptables
规则:sudo iptables -L
这应该返回空规则列表,或显示
ACCEPT
为默认策略。
5. 禁用 firewalld
(如果启用)
如果你的系统使用 firewalld
,你可以使用以下命令禁用它:
# 停止 firewalld 服务
sudo systemctl stop firewalld
# 禁用 firewalld 服务,确保它在重启时不再启动
sudo systemctl disable firewalld
4、配置完后ping一下看看通不通(101是主机,102是虚拟机,103是开发板)
有个注意的地方,如果可以ping通主机,却不能ping通虚拟机,需要查看虚拟机的网络情况,且虚拟机不能联wifi(或关闭主机wifi)。

注意看虚拟机的网络设置


5、ping通之后,我们运行我们的代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <iostream>
#include <pthread.h>
#include <semaphore.h>
#include <sys/select.h>
#include <sys/times.h>
#include <sys/epoll.h>
// 服务端函数
void server102(int port)
{
int serv_sock{}, clnt_sock{};
struct sockaddr_in serv_adr{}, clnt_adr{};
socklen_t clnt_sz = sizeof(clnt_adr);
char buf[1024] = ""; // 收发缓冲区
serv_sock = socket(PF_INET, SOCK_STREAM, 0);
if (serv_sock == -1) {
perror("socket error");
return;
}
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_adr.sin_port = htons(port);
// 绑定
if (bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)) == -1) {
perror("bind error");
close(serv_sock);
return;
}
// 监听
if (listen(serv_sock, 5) == -1) {
perror("listen error");
close(serv_sock);
return;
}
// epoll
epoll_event event;
int epfd = epoll_create(1);
if (epfd == -1) {
perror("epoll_create error");
close(serv_sock);
return;
}
epoll_event* all_events = new epoll_event[100];
event.events = EPOLLIN;
event.data.fd = serv_sock;
epoll_ctl(epfd, EPOLL_CTL_ADD, serv_sock, &event);
while (true) {
int event_cnt = epoll_wait(epfd, all_events, 100, 1000);
if (event_cnt == -1) {
perror("epoll_wait error");
break;
}
if (event_cnt == 0) continue;
for (int i = 0; i < event_cnt; i++) {
if (all_events[i].data.fd == serv_sock) {
clnt_sz = sizeof(clnt_adr);
clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_adr, &clnt_sz);
if (clnt_sock == -1) {
perror("accept error");
continue;
}
event.events = EPOLLIN;
event.data.fd = clnt_sock;
epoll_ctl(epfd, EPOLL_CTL_ADD, clnt_sock, &event);
printf("client is connected! %d\n", clnt_sock);
} else {
ssize_t len = read(all_events[i].data.fd, buf, sizeof(buf));
if (len <= 0) {
epoll_ctl(epfd, EPOLL_CTL_DEL, all_events[i].data.fd, NULL);
close(all_events[i].data.fd);
printf("client is closed! %d\n", all_events[i].data.fd);
} else {
write(all_events[i].data.fd, buf, len);
}
}
}
}
delete[] all_events;
close(serv_sock);
close(epfd);
}
// 客户端函数
void client102(const char* ip, int port)
{
int cln_sock = socket(PF_INET, SOCK_STREAM, 0);
if (cln_sock == -1) {
perror("socket error");
return;
}
struct sockaddr_in serv_adr;
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = inet_addr(ip);
serv_adr.sin_port = htons(port);
if (connect(cln_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)) == -1) {
perror("connect error");
close(cln_sock);
return;
}
char message[256] = "";
while (true) {
printf("Input message(q/Q to quit): ");
fgets(message, sizeof(message), stdin);
if (!strcmp(message, "q\n") || !strcmp(message, "Q\n")) break;
write(cln_sock, message, strlen(message));
memset(message, 0, sizeof(message));
read(cln_sock, message, sizeof(message));
printf("server: %s\n", message);
}
close(cln_sock);
}
// 解析命令行参数
void lession102(int argc, char* argv[])
{
if (argc < 3) {
fprintf(stderr, "Usage: ./myepoll s <port> | ./myepoll c <ip> <port>\n");
exit(EXIT_FAILURE);
}
if (strcmp(argv[1], "s") == 0) {
// 服务端
int port = atoi(argv[2]);
server102(port);
} else if (strcmp(argv[1], "c") == 0) {
// 客户端
if (argc < 4) {
fprintf(stderr, "Client mode requires <ip> and <port>\n");
exit(EXIT_FAILURE);
}
const char* ip = argv[2];
int port = atoi(argv[3]);
client102(ip, port);
} else {
fprintf(stderr, "Invalid option: %s\n", argv[1]);
exit(EXIT_FAILURE);
}
}
int main(int argc, char* argv[])
{
lession102(argc, argv);
return 0;
}
我们在虚拟机上编译一下生成可执行文件,首先是在虚拟机运行的版本
由于开发板是体系,我们还需要生成一个arm版本的可执行文件
如果没有工具,先安装。
sudo apt update
sudo apt install g++-aarch64-linux-gnu
编译
aarch64-linux-gnu-g++ -std=c++11 -o myepoll01 epolltest.cpp -pthread
把新的可执行文件复制到开发板。
以下展示效果:
首先,开发板我们先查看eth0和eth1哪个再用,,我们用的eth0,将开发板当服务器,虚拟机当客户端
接着用开发半当客户端,虚拟机当服务器