v831-T113-c-udp发送篇
又来分析udp,目标是从v831中获取到的图片信息发送给t113然后再屏幕上显示出来
挫折一
t113作为服务端,再接收到客户端发来的数据后会自动设置clinetaddr,那么我们就不再需要取从新aton这个ip地址了,直接使用clientaddr
int udp_send(void)
{
// if (0 == inet_aton("192.168.1.118", &tSocketClientAddr.sin_addr)){
// printf("invalid server_ip\n");
// return -1;
// }
// printf("aton\n");
iAddrLen = sizeof(struct sockaddr);
iRecvLen = sendto(iSocketServer, "ok", 3, 0,
(struct sockaddr *)&tSocketClientAddr, iAddrLen);
if (iRecvLen < 0)
{
printf("send error \n");
return -1;
}
// printf("send\n");
return 0;
}
int udp_rec(unsigned char *ucRecvBuf)
{
int size;
iAddrLen = sizeof(struct sockaddr);
iRecvLen = recvfrom(iSocketServer, ucRecvBuf, 240*240*3, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);
if (iRecvLen > 0)
{
ucRecvBuf[iRecvLen] = '\0';
printf("Get Msg From %s : \n", inet_ntoa(tSocketClientAddr.sin_addr));
for(size=0;size<iRecvLen;size++)
{
printf("%x",ucRecvBuf[size]);
}
}
else{
return -1;
}
return 0;
}
挫折二
sendto,这个函数再tcp中是会自动拆分的,因为最大数据包的问题,不可能全部数据一贞发送完,但是再udp中就不会自动拆分,所以在程序中我们应该手动拆分帧。根据百度的结果最大数据长度为:
int upd_send()
{
int iSocketClient;
struct sockaddr_in tSocketServerAddr;
struct sockaddr_in tSocketClientAddr;
libmaix_err_t err;
int iRet;
unsigned char ucSendBuf[1000];
int iSendLen;
int iAddrLen;
printf("\r\nsize is %d\r\n",cam->fram_size);
iSocketClient = socket(AF_INET, SOCK_DGRAM, 0);
tSocketServerAddr.sin_family = AF_INET;
tSocketServerAddr.sin_port = htons(SERVER_PORT); /* host to net, short */
//tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
if (0 == inet_aton(ip_add, &tSocketServerAddr.sin_addr))
{
printf("invalid server_ip\n");
return -1;
}
memset(tSocketServerAddr.sin_zero, 0, 8);
err = cam->start_capture(cam);
if(err != LIBMAIX_ERR_NONE){
printf("start capture fail: %s\n", libmaix_get_err_msg(err));
return -1;
}
while (1)
{
err = cam->capture_image(cam,&img);
if(err != LIBMAIX_ERR_NONE)
{
// not ready, sleep to release CPU
if(err == LIBMAIX_ERR_NOT_READY)
{
usleep(20 * 1000);
continue;
}
else
{
printf("capture fail: %s\n", libmaix_get_err_msg(err));
break;
}
}
iAddrLen = sizeof(struct sockaddr);
printf("data size is %d\r\n",sizeof(img->data));
iSendLen = sendto(iSocketClient, img->data,65507, 0,
(const struct sockaddr *)&tSocketServerAddr, iAddrLen);
if (iSendLen <= 0)
{
close(iSocketClient);
return -1;
}
while(( recvfrom(iSocketClient, ucSendBuf, 999, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen))<=0);
if(strcmp(ucSendBuf,"ok"))
{
printf("no ok \n");
printf("%s\n\n",ucSendBuf);
close(iSocketClient);
break;
}
printf("ok \n");
}
return 0;
}
挫折三
udp不要以数据的一贞为单位的发送再回复,因为这样会导致丢包而中断传输,所以尽量发送一次回复一次
t113:
#include "udp_lcd.h"
/* socket
* bind
* sendto/recvfrom
*/
#define SERVER_PORT 8888
struct sockaddr_in tSocketServerAddr;
struct sockaddr_in tSocketClientAddr;
int iSocketServer;
int iSocketClient;
int iAddrLen;
int iRecvLen;
int udp_send(void)
{
// if (0 == inet_aton("192.168.1.118", &tSocketClientAddr.sin_addr)){
// printf("invalid server_ip\n");
// return -1;
// }
// printf("aton\n");
iAddrLen = sizeof(struct sockaddr);
iRecvLen = sendto(iSocketServer, "ok", 3, 0,
(struct sockaddr *)&tSocketClientAddr, iAddrLen);
if (iRecvLen < 0)
{
printf("send error \n");
return -1;
}
// printf("send\n");
return 0;
}
int udp_rec(unsigned char *ucRecvBuf)
{
int size,total_size=0;
iAddrLen = sizeof(struct sockaddr);
iRecvLen = 0;
while(total_size<(240*240*3))
{
iRecvLen = recvfrom(iSocketServer, ucRecvBuf+total_size, 240*240*3, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);
if (iRecvLen > 0){
total_size+=iRecvLen;
}
else{
printf("error\n\n",total_size);
return -1;
}
udp_send();
}
return 0;
}
int udp_init()
{
int iRet;
//unsigned char ucRecvBuf[1000];
int iClientNum = -1;
iSocketServer = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == iSocketServer)
{
printf("socket error!\n");
return -1;
}
tSocketServerAddr.sin_family = AF_INET;
tSocketServerAddr.sin_port = htons(SERVER_PORT); /* host to net, short */
tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
memset(tSocketServerAddr.sin_zero, 0, 8);
iRet = bind(iSocketServer, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
if (-1 == iRet)
{
printf("bind error!\n");
return -1;
}
return 0;
}
int udp_end()
{
close(iSocketServer);
return 0;
}
v831
int udp_start(void){
iAddrLen = sizeof(struct sockaddr);
while(total_size<(240*240*3)){
if(((240*240*3)-total_size)>=65507){
iSendLen = sendto(iSocketClient,( img2->data)+total_size,65507, 0,
(const struct sockaddr *)&tSocketServerAddr, iAddrLen);
}
else{
iSendLen = sendto(iSocketClient,( img2->data)+total_size,(240*240*3)%65507, 0,
(const struct sockaddr *)&tSocketServerAddr, iAddrLen);
}
if (iSendLen <= 0)
{
printf("\n failed send\n");
close(iSocketClient);
return -1;
}
total_size+=iSendLen;
while(( recvfrom(iSocketClient, ucSendBuf, 999, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen))<=0);
if(strcmp(ucSendBuf,"ok"))
{
printf("no ok \n");
printf("%s\n\n",ucSendBuf);
close(iSocketClient);
break;
}
}
total_size=0;
return 0;
}
挫折四
大小端的问题,这个问题困扰了我一天了,v831发送的数据没有错误,只不过在强制转换的时候要注意大小端的问题,这是有关大小端的一篇文章
我的这块板子估计在转换的时候,char转换为int,由于大小端的问题,应该是大端模式,低地址放高数据。
改之后的代码
void rgb_to_argb(unsigned char *rgb,unsigned char *argb,int size)
{
int i;
printf("\r\ncolor is %8lx\r\n",*(unsigned int *)rgb);
for(i=0;i<(size/3);i++)
{
*(argb+3)=(unsigned char)0xff;
*(argb)=(*(rgb+2));
*(argb+1)=(*(rgb+1));
*(argb+2)=(*(rgb+0));
argb+=4;
rgb+=3;
}
}
主体的代码
t113:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "linux/fb.h"
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <string.h>
#include "udp_lcd.h"
uint32_t fb_line,fb_byte_per,fb_all_bit;
unsigned char *fb_base;
static struct fb_var_screeninfo var;
void rgb_to_argb(unsigned char *rgb,unsigned char *argb,int size)
{
int i;
for(i=0;i<(size/3);i++)
{
*(argb+3)=(unsigned char)0xff;
*(argb)=(*(rgb+2));
*(argb+1)=(*(rgb+1));
*(argb+2)=(*(rgb+0));
argb+=4;
rgb+=3;
}
}
void lcd_flash(unsigned int x,unsigned int y,int endx,int endy,unsigned int *buffer,unsigned int size)
{
unsigned int i;
unsigned int *fb_test=(unsigned int *)fb_base;
fb_test+=(unsigned int)(x+fb_line*y/4);//fb_line*0/4;//
for(i=0;i<size;i++)
{
*fb_test = (unsigned int)buffer[i];
// printf("\r\ncolor2 is %8.lx\r\n",buffer[i]);
if(!((i+1)%(endx+1))&&(i!=0)){
fb_test+=(unsigned int)(fb_line/4-endx);//800-239;//
}
else{
fb_test++;
}
// if(i==239*2)
// break;
}
}
int main()
{
unsigned char buf[240*240*4];
unsigned char rgbbuf[240*240*3];
int fb_handle;
fb_handle = open("/dev/fb0",O_RDWR);
if(fb_handle < 0)
{
return -1;
}
memset(buf,-1,sizeof(buf));
if(ioctl(fb_handle,FBIOGET_VSCREENINFO,&var))//使用获取动态数据的标志符从驱动获取屏幕数据
{
return -1;
}
////////获取屏幕的数据
fb_line = var.xres * var.bits_per_pixel / 8;//长度
fb_byte_per = var.bits_per_pixel / 8;
fb_all_bit = var.xres * var.yres * var.bits_per_pixel / 8;//总贞数
////////对文件进行映射
fb_base = (unsigned char *)mmap(NULL , fb_all_bit, PROT_READ | PROT_WRITE, MAP_SHARED, fb_handle, 0);
if(fb_base == (unsigned char *)-1)
{
printf("failed to mmap");
return -1;
}
printf("bpp is %d\r\n all is %d\r\n x is %d y is %d\r\n",var.bits_per_pixel,var.xres*var.yres,var.xres,var.yres);
udp_init();
lcd_flash(10,0,239,239,buf,240*240);
while(1){
if(!udp_rec(rgbbuf))
{
rgb_to_argb(rgbbuf,(unsigned int *)buf,240*240*3);
lcd_flash(10,0,239,239,(unsigned int *)buf,240*240);
}
else
{}
}
//memset(fb_base, 0xf0, fb_all_bit);//清个白屏试试
udp_end();
munmap(fb_base,fb_all_bit);
close(fb_handle);
}
v831:
#include "stdio.h"
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "global_config.h"
#include "global_build_info_time.h"
#include "global_build_info_version.h"
#include "main.h"
#include <sys/time.h>
#include <unistd.h>
#include <math.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include "libmaix_cam.h"
#include "libmaix_image.h"
#include "libmaix_disp.h"
#include "libmaix_cv_image.h"
#define ip_add "192.168.1.124"
#define SERVER_PORT 8888
struct libmaix_cam* cam = NULL;
libmaix_image_t* img;
libmaix_image_t *t = NULL;
libmaix_image_t *img2= NULL;
int iSendLen;
int iAddrLen;
int total_size=0;
int iSocketClient;
unsigned char ucSendBuf[1000];
struct sockaddr_in tSocketServerAddr;
struct sockaddr_in tSocketClientAddr;
int camera_init(void){
}
int camera_end(void){
}
int udp_start(void){
iAddrLen = sizeof(struct sockaddr);
while(total_size<(240*240*3)){
if(((240*240*3)-total_size)>=65507){
iSendLen = sendto(iSocketClient,( img2->data)+total_size,65507, 0,
(const struct sockaddr *)&tSocketServerAddr, iAddrLen);
}
else{
iSendLen = sendto(iSocketClient,( img2->data)+total_size,(240*240*3)%65507, 0,
(const struct sockaddr *)&tSocketServerAddr, iAddrLen);
}
if (iSendLen <= 0)
{
printf("\n failed send\n");
close(iSocketClient);
return -1;
}
total_size+=iSendLen;
while(( recvfrom(iSocketClient, ucSendBuf, 999, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen))<=0);
if(strcmp(ucSendBuf,"ok"))
{
printf("no ok \n");
printf("%s\n\n",ucSendBuf);
close(iSocketClient);
break;
}
}
total_size=0;
return 0;
}
int upd_send()
{
cam = libmaix_cam_create(0, 240, 240, 1, 0);
libmaix_camera_module_init();
libmaix_image_module_init();
struct libmaix_disp* disp = libmaix_disp_create(0);
disp->height=240;disp->width=240;
libmaix_err_t err;
int iRet;
printf("\r\nsize is %d\r\n",cam->fram_size);
iSocketClient = socket(AF_INET, SOCK_DGRAM, 0);
tSocketServerAddr.sin_family = AF_INET;
tSocketServerAddr.sin_port = htons(SERVER_PORT); /* host to net, short */
//tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
if (0 == inet_aton(ip_add, &tSocketServerAddr.sin_addr))
{
printf("invalid server_ip\n");
return -1;
}
memset(tSocketServerAddr.sin_zero, 0, 8);
err = cam->start_capture(cam);
libmaix_cam_t* cam2 = libmaix_cam_create(1, 240, 240, 1, 0);
err = cam2->start_capture(cam2);
if(err != LIBMAIX_ERR_NONE){
printf("start capture fail: %s\n", libmaix_get_err_msg(err));
return -1;
}
while (1)
{
err = cam->capture_image(cam,&img2);
err = cam2->capture_image(cam2,&t);
if(err != LIBMAIX_ERR_NONE)
{
// not ready, sleep to release CPU
if(err == LIBMAIX_ERR_NOT_READY)
{
usleep(20 * 1000);
continue;
}
else
{
printf("capture fail: %s\n", libmaix_get_err_msg(err));
break;
}
}
// for(i=0;i<57600;i++){
// libmaix_cv_image_set_pixel(img2,i/240,i%240,MaixColor(0,0xff,0));
// }
// printf("\r\ncolor is %8x\r\n",*(unsigned int *)(img2->data));
udp_start();
disp->draw_image(disp,img2);
}
libmaix_image_destroy(&img2);
libmaix_image_destroy(&img);
libmaix_cam_destroy(&cam);
libmaix_disp_destroy(&disp);
libmaix_cam_destroy(&cam2);
libmaix_image_destroy(&t);
libmaix_image_module_deinit();
libmaix_camera_module_deinit();
return 0;
}
int main(int argc, char* argv[])
{
camera_init();
upd_send();
camera_end();
return 0;
}
分类:
v831_c
, t113_c_tina
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」