粤嵌实训(笔记)

news2024/12/1 0:26:12

目录

1. LCD换自己喜欢的颜色

 2. LCD换个图案

 3. LCD换张图片

4.网线登录

ifconfig eth0 192.168.5.9

5.触屏电子相册

6.网络编程(TCP通信)

 7.网络编程(UDP通信)


说实话,对于这个粤嵌的实训,真的有很多想吐槽的地方,以下就是粤嵌给的一块板子,屏幕已经碎了,只有一根串口线(甚至是RS232,tm的)和一根DC电源(可能是为了省成本,要我就整个TYPEC供电了),它甚至一条MIRCOusb都不给(接OTG,后来我发现adb传输用不了,可能是这块板子OTG口需要特定的驱动,是的,我没资料),网线也没给,tftp,nfs都没法用,后面发现它竟然是用板载的一个rx工具(当时真是知识盲区),对比我用的一块全志的T113的板子,这块板子真的寄。

 吐槽完就进入正题吧,就是关于整个实训的各个实验:

1. LCD换自己喜欢的颜色

对于传输文件,我这里就统一用TFTP传输了

环境配置过程:

1.在windows环境下创建一个share文件,就用来存需要传到开发板的文件。

 2.关掉防火墙(记得把那些360之类的也关了,下面的是防火墙关闭工具)

链接:https://pan.baidu.com/s/1R5ycBw-_kbUw-jruMJyZmQ 
提取码:1234 

3.TFTP工具配置

链接:https://pan.baidu.com/s/18gele0YKJ_-J2cbJhg-QuQ 
提取码:1234 

 就改这两个,一个是share文件夹的路径,一个是本机的ip

4.把开发板IP改成与本机IP同一网段(因为我本机IP是192.168.5.10,开发板就改成192.168.5.9)

ifconfig eth0 192.168.5.9

 5.尝试ping通本机IP

6.TFTP传输

 我在share文件夹下放了一张BMP格式的图片

 tftp 192.168.5.10 -g -r func.bmp

参数的详情见这篇博客 Linux命令之tftp常用参数说明_小小小羊羊羊的博客-CSDN博客_tftp参数这玩意主要是快啊,比rx快太多了,如果你还是没配出来,那建议参考韦东山老师的配置双网卡的教程走一遍,其实我在玩粤嵌这块板子前是先去玩了T113的开发板,试着走驱动开发方向,但没办法,既然学校强制学习应用开发,那就来吧!(鸡汤)

 然后还是正题,就是显示个喜欢的颜色,很简单哈。

代码贴出来,扔到ubuntu拿交叉编译工具链跑就行

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

//ssize_t write(int fd, const void *buf, size_t count);
//int open(const char *pathname, int flags);

int main()
{
	//1.打开屏幕
	int fd=0; //接受open的返回值 
	fd=open("/dev/fb0", O_RDWR);
	if(fd==-1) //做错误判断
	{
		perror("open hello.c fail");
	}

	//2.写入颜色数据
	int w_ret=0;
	int i=0;
	int j=0;
	unsigned int color[480][800]={0};
	
	for(i=0;i<480;i++)
	{
		for(j=0;j<800;j++)
		{
			color[i][j]=0xff0000; //红色 
		}
		
	}

	w_ret=write(fd, color, 480*800*4);
	if(w_ret==-1)//做错误判断
	{
		perror("write fail");
	}
	
	//3.关闭文件
	close(fd);
}

arm-linux-gnueabi-gcc -o LCD LCD.c 

 因为用的是自己的编译环境就直接搞了,编译出来的程序文件已经框出来了。

TFTP传输进去开发板,然后添加运行权限运行。

tftp 192.168.5.10 -g -r LCD1
chmod 777 LCD1
./LCD1

 代码效果如下,实在有点简单,代码就不改了。

 2. LCD换个图案

代码贴出来,操作也是和上面那个实验类似。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

//ssize_t write(int fd, const void *buf, size_t count);
//int open(const char *pathname, int flags);

int main()
{
	//1.打开屏幕
	int fd=0; //接受open的返回值 
	fd=open("/dev/fb0", O_RDWR);
	if(fd==-1) //做错误判断
	{
		perror("open hello.c fail");
	}

	//2.写入颜色数据
	int w_ret=0;
	int i=0;
	int j=0;
	unsigned int color[480][800]={0};
	
	for(i=0;i<480;i++)
	{
		for(j=0;j<800;j++)
		{
			if((j-400)*(j-400)+(i-240)*(i-240)<=200*200) //(x-x0)*(x-x0) + (y-y0)*(y-y0) =r*r
			{
				color[i][j]=0xff0000; //红色 
			}
			else
			{
				color[i][j]=0x000000; //黑色 
			}
		}
		
	}


	w_ret=write(fd, color, 480*800*4);
	if(w_ret==-1)//做错误判断
	{
		perror("write fail");
	}
	
	//3.关闭文件
	close(fd);
}

arm-linux-gnueabi-gcc -o LCD2 LCD.c

 tftp 192.168.5.10 -g -r LCD2
chmod 777 LCD2
./LCD2

 

效果如上,因为前面的三个LCD实验比较简单,过得快一点了,后面的网络编程才是重头戏 

 3. LCD换张图片

代码贴在这里,图片用的是我在实验一用TFTP传输过去的那张,像素为800*480,必须为BMP格式,且必须命名(func.bmp)图片不是我做的,虽然我会,但我不想自己整一张了,就沿用别人发的图片吧

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>

//off_t lseek(int fd, off_t offset, int whence);
//ssize_t read(int fd, void *buf, size_t count);
//ssize_t write(int fd, const void *buf, size_t count);
//int open(const char *pathname, int flags);


int main()
{
	//1.打开屏幕
	int fd=0; //接受open的返回值 
	fd=open("/dev/fb0", O_RDWR);
	if(fd==-1) //做错误判断
	{
		perror("open fb0 fail");
	}
	//打开图片
	int bmp_fd=0; //接受open的返回值 
	bmp_fd=open("./func.bmp", O_RDWR);
	if(bmp_fd==-1) //做错误判断
	{
		perror("open func.bmp fail");
	}
	
	
	//2.偏移54字节
	lseek(bmp_fd,54,SEEK_SET);

	//3.读取像素数据 800*480
	unsigned char bmp[800*480*3]={0};
	
	read(bmp_fd,bmp,sizeof(bmp));
	//4.数据处理
/*
bmp[0]--B
bmp[1]--G
bmp[2]--R
bmp[3]--B
....
lcd[0]=bmp[0] | bmp[1]<<8 | bmp[2]<<16;
lcd[1]=bmp[3] | bmp[4]<<8 | bmp[5]<<16;
lcd[2]=bmp[6] | bmp[7]<<8 | bmp[8]<<16;
*/	
	unsigned int lcd[800*480]={0};
	int i=0;
	int j=0;
	for(i=0;i<800*480;i++)
	{
		lcd[i]=bmp[3*i] | bmp[3*i+1]<<8 | bmp[3*i+2]<<16;
	}

	//5.写入屏幕
	int w_ret=0;
	w_ret=write(fd, lcd, sizeof(lcd));
	if(w_ret==-1)//做错误判断
	{
		perror("write fail");
	}
	
	//6.关闭文件
	close(bmp_fd);
	close(fd);
}

arm-linux-gnueabi-gcc -o LCD3 LCD.c

tftp 192.168.5.10 -g -r LCD3
chmod 777 LCD3
./LCD3

 

效果如上,可以看到图片是颠倒的。下面贴个如何把图片正过来的代码。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>

//off_t lseek(int fd, off_t offset, int whence);
//ssize_t read(int fd, void *buf, size_t count);
//ssize_t write(int fd, const void *buf, size_t count);
//int open(const char *pathname, int flags);


int main()
{
	//1.打开屏幕
	int fd=0; //接受open的返回值 
	fd=open("/dev/fb0", O_RDWR);
	if(fd==-1) //做错误判断
	{
		perror("open fb0 fail");
	}
	//打开图片
	int bmp_fd=0; //接受open的返回值 
	bmp_fd=open("./func.bmp", O_RDWR);
	if(bmp_fd==-1) //做错误判断
	{
		perror("open func.bmp fail");
	}
	
	
	//2.偏移54字节
	lseek(bmp_fd,54,SEEK_SET);

	//3.读取像素数据 800*480
	unsigned char bmp[800*480*3]={0};
	
	read(bmp_fd,bmp,sizeof(bmp));
	//4.数据处理
/*
bmp[0]--B
bmp[1]--G
bmp[2]--R
bmp[3]--B
....
lcd[0]=bmp[0] | bmp[1]<<8 | bmp[2]<<16;
lcd[1]=bmp[3] | bmp[4]<<8 | bmp[5]<<16;
lcd[2]=bmp[6] | bmp[7]<<8 | bmp[8]<<16;
*/	
	unsigned int temp[800*480]={0};
	unsigned int lcd[800*480]={0};
	int i=0;
	int j=0;
	for(i=0;i<800*480;i++)
	{
		temp[i]=bmp[3*i] | bmp[3*i+1]<<8 | bmp[3*i+2]<<16;
	}
	
	for(i=0;i<480;i++)
	{
		for(j=0;j<800;j++)
		{
			lcd[(480-1-i)*800+j]=temp[i*800+j];
		}
		
	}
	//5.写入屏幕
	int w_ret=0;
	w_ret=write(fd, lcd, sizeof(lcd));
	if(w_ret==-1)//做错误判断
	{
		perror("write fail");
	}
	
	//6.关闭文件
	close(bmp_fd);
	close(fd);
}

 这里省去交叉编译的过程图

 效果图如上,其实就是把图反着写入。

在这里把执行的程序文件放上来,大伙自己烧板子自己试哈

链接:https://pan.baidu.com/s/1BuQ5Q2FEGbgdJ1yEr4o86w 
提取码:1234 

4.网线登录

啧...我觉得这个可能没太大必要,虽然好像可以省一个串口,但还不如串口换成个带5V的TYPEC,也是两条线,搞这个不如整个WiFi模块远程无线调试,我不做了,但里面有一个过程比较有价值,就是更改开机脚本的

vi /etc/profile

其实就是改ifconfig之后得到的开发板的网卡IP,我这里是改成了192.168.5.9,需要的话改,不需要就每次开机都输入一条

ifconfig eth0 192.168.5.9

5.触屏电子相册

我靠,晴天霹雳,完成这东西需要整多几张图,太难受了

 然后在图画另存为bmp格式就行,我做的是这三张。

 下面贴出代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/input.h>


//void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);

//off_t lseek(int fd, off_t offset, int whence);
//ssize_t read(int fd, void *buf, size_t count);
//ssize_t write(int fd, const void *buf, size_t count);
//int open(const char *pathname, int flags);
//函数声明
int show_bmp(const char *bmpname);
int show_anybmp(const char *bmpname);
int show_anywherebmp(int x0,int y0,const char *bmpname);
int get_xy(int *x,int *y);

int main()
{
	int x=-1;
	int y=-1;
    	int tmp=0;
	char photo[][30]={"./1.bmp","./2.bmp","./3.bmp"};
	//1.显示主界面
	show_anybmp("./func.bmp"); //规则界面
	while(1)
	{
		//2.获取坐标
		get_xy(&x,&y);

		if(x>=400) //下一张
		{
			tmp=(tmp+1)%3;
			show_bmp(photo[tmp]);
		}
		else if(x<400) //上一张
		{
			tmp=tmp-1;
			if(tmp==-1){
				tmp=2;
			}
			show_bmp(photo[tmp]);
		}
		
		//用完坐标得清零 坐标
		x=-1;
		y=-1;
	}
	
	
}

//函数实现
//显示800*480的图片
int show_bmp(const char *bmpname)
{
	//1.打开屏幕
	int fd=0; //接受open的返回值 
	fd=open("/dev/fb0", O_RDWR);
	if(fd==-1) //做错误判断
	{
		perror("open fb0 fail");
	}
	
	//建立屏幕映射
	unsigned int* lcd = mmap(NULL, 800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
	
	
	//打开图片
	int bmp_fd=0; //接受open的返回值 
	bmp_fd=open(bmpname, O_RDWR);
	if(bmp_fd==-1) //做错误判断
	{
		perror("open func.bmp fail");
	}
	
	
	//2.偏移54字节
	lseek(bmp_fd,54,SEEK_SET);

	//3.读取像素数据 800*480
	unsigned char bmp[800*480*3]={0};
	
	read(bmp_fd,bmp,sizeof(bmp));
	//4.数据处理
/*
bmp[0]--B
bmp[1]--G
bmp[2]--R
bmp[3]--B
....
lcd[0]=bmp[0] | bmp[1]<<8 | bmp[2]<<16;
lcd[1]=bmp[3] | bmp[4]<<8 | bmp[5]<<16;
lcd[2]=bmp[6] | bmp[7]<<8 | bmp[8]<<16;
*/	
	unsigned int temp[800*480]={0};
	int i=0;
	int j=0;
	for(i=0;i<800*480;i++)
	{
		temp[i]=bmp[3*i] | bmp[3*i+1]<<8 | bmp[3*i+2]<<16;
	}
	
	//解决上下颠倒  把一维数组 二维化思考
	for(i=0;i<480;i++)
	{
		for(j=0;j<800;j++)
		{
			lcd[(480-1-i)*800+j]=temp[i*800+j];
		}
		
	}
	
	
	//解除映射
	munmap(lcd,800*480*4);
	
	//6.关闭文件
	close(bmp_fd);
	close(fd);	
}


//显示任意大小图片
int show_anybmp(const char *bmpname)
{
	//1.打开屏幕
	int fd=0; //接受open的返回值 
	fd=open("/dev/fb0", O_RDWR);
	if(fd==-1) //做错误判断
	{
		perror("open fb0 fail");
	}
	
	//建立屏幕映射
	unsigned int* lcd = mmap(NULL, 800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
	
	
	//打开图片
	int bmp_fd=0; //接受open的返回值 
	bmp_fd=open(bmpname, O_RDWR);
	if(bmp_fd==-1) //做错误判断
	{
		perror("open func.bmp fail");
	}
	
	
	
	
	//2.偏移54字节
	//先提取到宽
	lseek(bmp_fd,18,SEEK_SET);
	int w=0;
	read(bmp_fd,&w,4);
	//printf("w=%d\n",w);//打印宽度信息
	//再提取高
	lseek(bmp_fd,22,SEEK_SET);
	int h=0;
	read(bmp_fd,&h,4);
	//printf("h=%d\n",h);//打印宽度信息
	
	
	lseek(bmp_fd,54,SEEK_SET);

	//3.读取像素数据 800*480
	unsigned char bmp[w*h*3];
	
	read(bmp_fd,bmp,sizeof(bmp));
	//4.数据处理
/*
bmp[0]--B
bmp[1]--G
bmp[2]--R
bmp[3]--B
....
lcd[0]=bmp[0] | bmp[1]<<8 | bmp[2]<<16;
lcd[1]=bmp[3] | bmp[4]<<8 | bmp[5]<<16;
lcd[2]=bmp[6] | bmp[7]<<8 | bmp[8]<<16;
*/	
	unsigned int temp[800*480]={0};
	int i=0;
	int j=0;
	for(i=0;i<w*h;i++)
	{
		temp[i]=bmp[3*i] | bmp[3*i+1]<<8 | bmp[3*i+2]<<16;
	}
	
	//解决上下颠倒  把一维数组 二维化思考
	for(i=0;i<h;i++)
	{
		for(j=0;j<w;j++)
		{
			lcd[(h-1-i)*800+j]=temp[i*w+j];
		}
		
	}
	
	
	//解除映射
	munmap(lcd,800*480*4);
	
	//6.关闭文件
	close(bmp_fd);
	close(fd);
} 

//在指定位置显示图片 x0,y0为起点坐标
int show_anywherebmp(int x0,int y0,const char *bmpname)
{
	//1.打开屏幕
	int fd=0; //接受open的返回值 
	fd=open("/dev/fb0", O_RDWR);
	if(fd==-1) //做错误判断
	{
		perror("open fb0 fail");
	}
	
	//建立屏幕映射
	unsigned int* lcd = mmap(NULL, 800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
	
	
	//打开图片
	int bmp_fd=0; //接受open的返回值 
	bmp_fd=open(bmpname, O_RDWR);
	if(bmp_fd==-1) //做错误判断
	{
		perror("open func.bmp fail");
	}
	
	
	
	
	//2.偏移54字节
	//先提取到宽
	lseek(bmp_fd,18,SEEK_SET);
	int w=0;
	read(bmp_fd,&w,4);
	printf("w=%d\n",w);//打印宽度信息
	//再提取高
	lseek(bmp_fd,22,SEEK_SET);
	int h=0;
	read(bmp_fd,&h,4);
	printf("h=%d\n",h);//打印宽度信息
	
	
	lseek(bmp_fd,54,SEEK_SET);

	//3.读取像素数据 800*480
	unsigned char bmp[w*h*3];
	
	read(bmp_fd,bmp,sizeof(bmp));
	//4.数据处理
/*
bmp[0]--B
bmp[1]--G
bmp[2]--R
bmp[3]--B
....
lcd[0]=bmp[0] | bmp[1]<<8 | bmp[2]<<16;
lcd[1]=bmp[3] | bmp[4]<<8 | bmp[5]<<16;
lcd[2]=bmp[6] | bmp[7]<<8 | bmp[8]<<16;
*/	
	unsigned int temp[800*480]={0};
	int i=0;
	int j=0;
	for(i=0;i<w*h;i++)
	{
		temp[i]=bmp[3*i] | bmp[3*i+1]<<8 | bmp[3*i+2]<<16;
	}
	
	//解决上下颠倒  把一维数组 二维化思考
	for(i=0;i<h;i++)
	{
		for(j=0;j<w;j++)
		{
			lcd[(h-1-i+y0)*800+j+x0]=temp[i*w+j];
		}
		
	}
	
	
	//解除映射
	munmap(lcd,800*480*4);
	
	//6.关闭文件
	close(bmp_fd);
	close(fd);	
}

int get_xy(int *x,int *y)
{

	int count=0;
	//1.打开触摸屏
	int tsfd =open("/dev/input/event0",O_RDWR);
	if(tsfd == -1)
	{
		perror("open ts fail");
	}
	
	//2.read
	struct input_event ts;
	
	while(1)
	{
		read(tsfd,&ts,sizeof(struct input_event));
		
		//筛选
		if(ts.type ==EV_ABS && ts.code==ABS_X )
		{ 
			*x=ts.value; //适合蓝底屏幕
			//*x= ts.value*800/1024;   //适合黑底屏幕
			count++;
		}
		
		if(ts.type ==EV_ABS && ts.code==ABS_Y )
		{
			*y=ts.value; //适合蓝底屏幕
			//*y= ts.value*480/600;   //适合黑底屏幕
			
			count++;
		}
		if(count == 2)
		{
			break;
		}
	}
	
	//关闭触摸屏
	close(tsfd);
}




arm-linux-gnueabi-gcc -o touch LCD_drv_touch.c

 

 

 效果如下:

效果

6.网络编程(TCP通信)

因为我没听课,所以就不知道他做的什么内容了..这部分我确实没学过,本来打算是寒假去学的,刚刚好,他竟然教了。

前面还有一个多线程的实验,因为不难我就不做了,拿gcc编译工具在UBUNTU上跑就行

代码贴出来

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/input.h>
#include <pthread.h>

//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

//线程任务函数
void *pth_function1(void *arg)
{
	while(1)
	{
		printf("你真帅!!!\n");
		sleep(1);//延时一秒
	}
	
	
}

//主线程
int main()
{
	
	pthread_t  thid; //定义线程ID
	
	//创建一个新的线程,默认属性  任务函数     不传参
	pthread_create(&thid, NULL, pth_function1, NULL);
	
	
	while(1)
	{
		printf("年轻人不讲武德!!!\n");
		sleep(1);//延时一秒
	}
	
}
gcc pth.c -o pth -pthread

 然后是第一个实验,TCP的客户端与服务端间的通信

ifconfig

 需要改这里:

 服务端代码:(server.c)

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <linux/input.h>

//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
//int listen(int sockfd, int backlog);
//int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
//int socket(int domain, int type, int protocol);

int main()
{
	//1.创建socket
	int skfd=socket(AF_INET ,SOCK_STREAM, 0);
	if(skfd == -1)
	{
		perror("socket fail");
	}
	else
	{
		printf("socket ok\n");
	}
	
	//2.bind IP和端口号
	//定义结构体
	struct sockaddr_in  seraddr={0};
	
	seraddr.sin_family=AF_INET; //IPV4
	seraddr.sin_port= htons(12345);
	//端口号 http-80 8080  Telnet--23 范围:0~65535  个人编程的时候建议5位数的端口号
	//htons()  把本地转换为网络序  认识大端和小端存储
	seraddr.sin_addr.s_addr=htonl(INADDR_ANY);
	//htonl() 课后 认识一下  转换为网络序  INADDR_ANY--0.0.0.0--表示自动获取本机IP
	
	int b_ret=bind(skfd, (struct sockaddr*)&seraddr,sizeof(seraddr));
	if(b_ret !=0)
	{
		perror("bind fail");
	}
	else
	{
		printf("bind ok\n");
	}
	
	//3.listen--等待连接
	int l_ret = listen(skfd,3);
	if(l_ret!=0)
	{
		perror("listen fail");
	}
	else
	{
		printf("listen ok\n");
	}
	
	//4.accept
	struct sockaddr_in  cliaddr={0}; //为了存储连接的客户端信息
	int len=sizeof(cliaddr);
	int newskfd=accept(skfd,(struct sockaddr*)&cliaddr, &len);
	if(newskfd == -1)
	{
		perror("accept fail");
		return -1;
	}
	else
	{
		printf("accept ok\n");
		printf("newskfd=%d,client-ip:%s,client-port:%d\n",newskfd,inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port));
		
	}
	
	//5.read/write  服务器一直接收
	char buf[1024]={0};
	while(1)
	{
		read(newskfd,buf,sizeof(buf)); //读取消息
		printf("buf=%s\n",buf); //打印消息
		
		if( strcmp(buf,"exit") == 0) //字符串的判断
		{
			break; //跳出循环  关闭通信
		}
		
		memset(buf,0,sizeof(buf)); //清空数组
	}
	
	
	//6. 关闭通信
	close(skfd);
	
}

 客户端代码:(client.c)

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <linux/input.h>
//int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
//int listen(int sockfd, int backlog);
//int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
//int socket(int domain, int type, int protocol);

int main()
{
	//1.创建socket
	int skfd=socket(AF_INET ,SOCK_STREAM, 0);
	if(skfd == -1)
	{
		perror("socket fail");
	}
	else
	{
		printf("socket ok\n");
	}
	
	//2.发起连接请求 connect
	struct sockaddr_in  seraddr={0};
	
	seraddr.sin_family=AF_INET; //IPV4
	seraddr.sin_port= htons(12345); 
	//端口号 http-80 8080  Telnet--23 范围:0~65535  个人编程的时候建议5位数的端口号
	//htons()  把本地转换为网络序  认识大端和小端存储
	seraddr.sin_addr.s_addr=inet_addr( "192.168.42.168"); //服务器的地址
	//htonl() 课后 认识一下  转换为网络序  INADDR_ANY--0.0.0.0--表示自动获取本机IP
	
	int c_ret=connect(skfd, (struct sockaddr*)&seraddr,sizeof(seraddr));
	if(c_ret!=0)
	{
		perror("connect fail");
		return -1;
	}
	else
	{
		printf("connect ok\n");
	}
	
	//3.read /write  通信:客户端一直发消息
	
	char buf[1024]={0};
	while(1)
	{
		printf("请输入要发送的消息:\n");
		scanf("%s",buf);
		write(skfd,buf,strlen(buf)); //发送消息
		if(strcmp(buf,"exit")==0) //判断消息为退出关键字
		{
			break;
		}
		printf("buf=%s\n",buf);
	}
	
	//4.关闭通信
	close(skfd);
}

 效果如下:

 7.网络编程(UDP通信)

直接贴代码了,比较简单,难在理解整个过程,不然代码是没法写的

 本机UBUNTUip为192.168.5.11,想要啥设备接收就写哪个设备的ip

服务端(server.c)

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <linux/input.h>

//ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);

int main()
{
	
	//1.创建socket
	int skfd=socket(AF_INET ,SOCK_DGRAM, 0);
	if(skfd == -1)
	{
		perror("socket fail");
	}
	else
	{
		printf("socket ok\n");
		printf("skfd=%d\n",skfd);
	}
	
	int s_ret=0; //返回值
	char buf[512]={0}; //存储读取内容
	struct sockaddr_in  seraddr={0}; //来自客户端地址
	
	seraddr.sin_family=AF_INET; //IPV4
	seraddr.sin_port= htons(12345); 
	//端口号 http-80 8080  Telnet--23 范围:0~65535  个人编程的时候建议5位数的端口号
	//htons()  把本地转换为网络序  认识大端和小端存储
	seraddr.sin_addr.s_addr=inet_addr( "192.168.5.11"); //服务器的地址
	//htonl() 课后 认识一下  转换为网络序  INADDR_ANY--0.0.0.0--表示自动获取本机IP
	
	
	
	socklen_t addrlen=sizeof(seraddr); //地址长度
	
	while(1)
	{
		printf("请输入发送的消息\n");
		scanf("%s",buf);
		s_ret=sendto(skfd,buf, strlen(buf),0,(struct sockaddr*)&seraddr, addrlen);
		//面试题 strlen 和 sizeof 对比
		if(s_ret==-1)
		{
			perror("sendto fail");
		}
		if(strcmp(buf,"exit")== 0)
		{
			break;
		}
		memset(buf,0,sizeof(buf)); //用完之后清空
	}
	
	//关闭通信
	close(skfd);
	
}

 客户端(client.c)

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <linux/input.h>

//ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);



int main()
{
	//1.创建socket
	int skfd=socket(AF_INET ,SOCK_DGRAM, 0);
	if(skfd == -1)
	{
		perror("socket fail");
	}
	else
	{
		printf("socket ok\n");
		printf("skfd=%d\n",skfd);
	}
	
	//2.bind IP和端口号
	//定义结构体
	struct sockaddr_in  seraddr={0};
	
	seraddr.sin_family=AF_INET; //IPV4
	seraddr.sin_port= htons(12345);
	//端口号 http-80 8080  Telnet--23 范围:0~65535  个人编程的时候建议5位数的端口号
	//htons()  把本地转换为网络序  认识大端和小端存储
	seraddr.sin_addr.s_addr=htonl(INADDR_ANY);
	//htonl() 课后 认识一下  转换为网络序  INADDR_ANY--0.0.0.0--表示自动获取本机IP
	
	int b_ret=bind(skfd, (struct sockaddr*)&seraddr,sizeof(seraddr));
	if(b_ret !=0)
	{
		perror("bind fail");
	}
	else
	{
		printf("bind ok\n");
	}
	
	int r_ret=0; //返回值
	char buf[512]={0}; //存储读取内容
	struct sockaddr_in  cliaddr={0}; //来自客户端地址
	socklen_t addrlen=sizeof(cliaddr); //地址长度
	
	while(1)
	{
		//接收消息
		r_ret=recvfrom(skfd, buf,sizeof(buf),0,(struct sockaddr*)&cliaddr, &addrlen);
		if(r_ret == -1)
		{
			perror("recvfrom fail");
		}
		else
		{
			printf("from %s:%s\n",inet_ntoa(cliaddr.sin_addr),buf);
		}
		
		if(strcmp(buf,"exit")==0)//判断消息内容
		{
			break;
		}
		
		memset(buf,0,sizeof(buf)); //用完之后清空
		memset(&cliaddr,0,sizeof(cliaddr));
		
	}
	
	//关闭通信
	close(skfd);
	
}

 尝试一下开发板和ubuntu通信:

好像不太行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/84710.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python 修改 网页 navigator 的属性的值

def init_js(page: Page, phone: str) -> Page:#修改 网页 navigator 的属性的值function fakeNav(key, value) {Object.defineProperty(navigator, key, {value: value,writable: false});}js_device_memory ffakeNav("deviceMemory", {gen_android_memory(phon…

Python测试题

目录 题目一&#xff1a;猜数字游戏 题目二&#xff1a;实现一个函数可判断一个数字是否为质数。 题目三&#xff1a;实现一个函数可判断一个数字是否为回文数。 题目四:编写程序实现中美汇率转换。 题目五:球体100米落地弹起运算 题目六&#xff1a;使用python建一个简易…

通达信交易接口API获取数据源码分享

在通达信交易接口下单之前&#xff0c;如何去了解快速获取交易数据呢&#xff1f;要是即使下单了&#xff0c;也不知道如何去查询&#xff0c;然后不管不问&#xff0c;等到需要你去止损了&#xff0c;你才回想起来去操作&#xff0c;这是很容易吃亏的做法的。在股票量化交易过…

符号三角形问题(Java)

符号三角形问题&#xff08;Java&#xff09; 文章目录符号三角形问题&#xff08;Java&#xff09;1、 前置介绍2、算法设计3、程序代码4、算法效率5、参考资料1、 前置介绍 符号三角形定义 如下图所示&#xff0c;符号三角形是由14个“” 号和14个"-"号组成的符号三…

k8s镜像下载不下来?利用 github Action 自己动手一次性解决难题,丰衣足食

docker-image-syncer 无论是在学习k8s还是正式环境部署k8s中,第一步安装k8难倒了各大英雄好汉。原因是k8s 各种组件镜像在谷歌服务器上(k8s.gcr.io)&#xff0c;而我们有墙的存在&#xff0c;所以会经常性的下载失败。解决办法是搭梯子&#xff0c;或者是使用其他镜像源。 本…

有符号变量与无符号变量之间的值的转换

1、有符号变量与无符号变量之间的值的转换 程序例子 涉及到的内容是&#xff1a; 有符号变量和无符号变量之间的转换 溢出&#xff08;如何判断&#xff09; #include<stdio.h> char getchar(int x, int y){char c;unsigned int a x;(x y > 10 ) ? (c 1): (c 2…

Linux——I/O复用(select的用法)

一、I/O复用 定义&#xff1a;I/O 复用使得程序能同时监听多个文件描述符&#xff0c;这对于提高程序的性能至关重要。 网络程序在下列情况下需要使用 I/O 复用技术&#xff1a; ◼ TCP 服务器同时要处理监听套接字和连接套接字。◼ 服务器要同时处理 TCP 请求和 UDP 请求。◼ …

RT-Thread的设备模型

RTT内核对象——设备 RT-Thread有多种内核对象&#xff0c;其中设备device就是其中一种。 内核继承关系图如下&#xff1a; 设备继承关系图如下&#xff1a; I/O 设备模型框架 应用程序通过 I/O 设备管理接口获得正确的设备驱动&#xff0c;然后通过这个设备驱动与底层 I/O 硬…

ARM通用中断控制器GIC之中断处理状态机 Interrupt handling state machine

中断有四种状态&#xff1a;inactive&#xff0c;pending&#xff0c;active 和active and pending。而产生中断的方式有两种&#xff0c;一种是通过写pending寄存器&#xff0c;让中断进入pending状态&#xff0c;可以忽略是否真的有物理中断信号&#xff0c;让Distributor将该…

如何构建myquant量化策略?

对于如何构建myquant量化策略这个问题而言&#xff0c;就是获取量化股票接口的基础数据&#xff0c;然后有了基础数据&#xff0c;才能对数据进行加工处理&#xff0c;构建量化策略&#xff0c;进行量化分析&#xff0c;回测和回溯。myquant量化策略主要是基于python进行量化投…

案例实操 | 利用Lambda函数来进行特征工程,超方便的!!

特征工程对于我们在机器学习的建模当中扮演着至关重要的角色&#xff0c;要是这一环节做得好&#xff0c;模型的准确率以及性能就被大大地被提升&#xff0c;今天小编就通过Python当中的lambda函数来对数据集进行一次特征工程的操作&#xff0c;生成一些有用的有价值的特征出来…

nacos--基础--3.4--集成--spring--spring上下文中的一些关键的特性

nacos–基础–3.4–集成–spring–spring上下文中的一些关键的特性 1、spring上下文中的一些关键的特性 注解驱动依赖注入外部化配置事件驱动 2、注解驱动 2.1、 启用 Nacos EnableNacos 是一个模块驱动的注解EnableNacos 支持 Nacos Spring 的所有功能 服务发现&#xff1…

香港服务器托管带宽怎么选?

香港服务器托管时&#xff0c;带宽的选择非常重要&#xff0c;带宽用量的大小不同&#xff0c;最终的费用也就会不同。用户在香港托管服务器的时候&#xff0c;应该选择多大的带宽才合适呢?应该如何选择香港服务器带宽大小呢? 香港服务器托管带宽怎么选? 其实&#xff0c;大…

5G无线技术基础自学系列 | 无线电波传播模型

素材来源&#xff1a;《5G无线网络规划与优化》 一边学习一边整理内容&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;5G无线技术基础自学系列 | 汇总_COCOgsta的博客-CSDN博客 无线电波传播模型用于预测无线电波在各…

JAVA开发(JWTUtil工具类实现token源码赏析)

一、token解决问题的背景&#xff1a; 1、 单点登录&#xff0c; 2、分布式登录状态&#xff0c; 3、在信任期内 避免 重新输入用户名密码登录。 4、跨系统免登陆等。 5、一些接口的请求权限验证。 总结以上token最终都是为了解决在在分布式系统中信任期内 避免 重新输入用户名…

如何选择合适的统计学方法

一般来说&#xff0c;使用哪种统计方法&#xff0c;取决于我们的应用场景、我们的研究目的是什么。 这里面一个麻烦的地方在于&#xff0c;不管你使用哪种统计方法&#xff0c;似乎都可以得出一个’结果’或一个p值&#xff0c;但这个结果有没有意义就两说了。 在我看来&…

【WEB安全】Xstream最新反序列化poc执行报错问题

前言 最近有个需求&#xff0c;用Xstream反序列化打个内存马&#xff0c;从通用性来讲&#xff0c;肯定用1.4.17的洞去打应用范围最广。众所周知&#xff0c;Xstream官方会提供其漏洞的poc。在我实验之下&#xff0c;1.4.17的几个poc只要涉及到任意java代码执行的都会报错&…

VMware创建共享文件夹并实现文件传输(Windows主机,Ubuntu虚拟机)

文章目录创建共享文件夹安装/更新VMware tool挂载共享文件夹共享文件夹的实现更改配置项&#xff0c;实现自动挂载&#xff08;推荐直接用这个&#xff09;数据传输参考博客创建共享文件夹 1、开启虚拟机的共享文件夹配置 首先在虚拟机中打开设置&#xff0c;在选项中点击共享…

Java springboot+vue+MySQLJava大型CRM客户关系管理源码带手机端和小程序源码 Java客户全流程高效管理CRM系统源码

springbootvue MySQL数据库 1. 前端&#xff1a;Vue 2. 后端&#xff1a;Spring boot 3. 数据库&#xff1a;MySQL 源码已经亲测 1. 前端&#xff1a;Vue 2. 后端&#xff1a;Spring boot 3. 数据库&#xff1a;MySQL 小程序是用UNIAPP开发的。 后台登录账户&#xff1a…

(附源码)springboot智能服药提醒app 毕业设计 102151

基于springboot智能服药提醒app 摘 要 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;智能服药提醒app程序被用户…