UDP通信写FLASH前必须先擦除

 Linux下不能向255.255.255.255发送udp广播 2013-12-18 15:37:47
分类: LINUX
转自:http://www.linuxidc.com/Linux/2012-09/69814.htm




我的ip是192.168.0.X, 路由IP是192.168.0.254,子网掩码255.255.255.0,广播发送的地址为255.255.255.255,Ubuntu下发送正常,然而在嵌入式linux设备里运行,sendto函数返回-1,perror显示network is unreachable.困扰了一天,后来看了多个帖子,受到了启发,问题解决。现在跟大家分享一下:
我添加了到255.255.255.255的路由就可以发送成功啊,添加的 命令是:
route add -net 255.255.255.255 netmask 255.255.255.255 dev eth0 metric 1
或者
route add -host 255.255.255.255 dev eth0
route add -host 239.255.255.250 dev eth0
这样就OK了!但是具体原理目前还不知道。












#include "recv.h"
#include <mtd/mtd-user.h>  
#include <sys/ioctl.h>


#define  BUFFER_LEN  1024
#define  LINTEN_PORT 9999
void ereaseFlash()
{
   int fp;
   fp = open ("/dev/mtd2", O_SYNC | O_RDWR ); 
   //printf("1---\n");
   if(fp == -1)
   {
      printf("can not open file!\n");
      return;
     
   }
   //重写FLASH之前必须先擦除相应区域,否则没效果
   erase_info_t erase;  
   mtd_info_t mtd;
   if (ioctl(fp, MEMGETINFO, &mtd) < 0) {  
            printf("MTD getinfo failed\n");  
            perror("get mtd info");   
            exit(0);   
    }
   erase.start =  mtd.size - mtd.erasesize;  
   erase.length =  mtd.erasesize;
   printf("start:%d   to:%d   blocksize:%d \n", mtd.erasesize - mtd.erasesize, mtd.size, mtd.erasesize);            
   //exit(0);                                           
   if (ioctl (fp, MEMERASE, &erase) < 0) {  
            printf("erase failed\n");  
            perror("erase mtd");  
            exit(0);  
    }  
    printf("erase  sucess\n");  
    
    close(fp);
}
int sendMsg(char* serverip, int port, unsigned char *sendinfo)
{
    int recvfd;
    struct sockaddr_in recvaddr;
    unsigned char buffer[BUFFER_LEN];
    bzero(&recvaddr, sizeof(struct sockaddr_in));
    recvfd = socket(AF_INET, SOCK_DGRAM, 0);
    
    const int opt = 1; 
    int nb = 0;  
nb = setsockopt(recvfd, SOL_SOCKET, SO_BROADCAST, (char *)&opt, sizeof(opt));  
if(nb == -1)  
{  
printf("set socket error... \n"); 
      close(recvfd); 
return -1;  
}
     
    recvaddr.sin_family = AF_INET;
    recvaddr.sin_port = htons(port);
    //recvaddr.sin_addr.s_addr = inet_addr(serverip);
    recvaddr.sin_addr.s_addr = inet_addr("255.255.255.255");
    
    memset(buffer, 0, BUFFER_LEN);
    strcpy(buffer, sendinfo);
 //sprintf(buf, "config ip success!");
    printf("send: %s \n", buffer);
if (sendto(recvfd, buffer, BUFFER_LEN, 0, (struct sockaddr *)&recvaddr, sizeof(struct sockaddr_in)) < 0)
{
printf("send error\n");
}
   close(recvfd);
}
int saveconfigx(char * configinfo)
{
   
   FILE *fp;
   char buf[BUFFER_LEN];
   int eof = 0; 
   
   ereaseFlash();
   
   fp = fopen("/dev/mtd2", "w+");     //rb, wb, w+


   if(fp == NULL)
   {
      printf("can not open file!\n");
      return -1;   
   }
   memset(buf, 0, BUFFER_LEN);
   strcpy(buf, configinfo);
   printf("SaveFlash:%s  \n", buf);
   eof = fseek(fp, -1024, SEEK_END);    //指向文件末尾 向前 偏移?量
   eof = fwrite(buf, 1024, 1, fp);
   fflush(fp);
   fseek(fp, -1024, SEEK_END);
   eof = fread(buf, 1024, 1, fp);
   printf("ReadFlash:%s  \n", buf);
   
   fclose(fp);
   
   system("./configip.out");
   return eof;
}
int readconfigx(char * buf)
{
   FILE *fp;
   int eof = 0; 
   fp = fopen("/dev/mtd2", "rb");     //rb, wb, w+


   if(fp == NULL)
   {
      printf("can not open file!\n");
      return -1;   
   }
   memset(buf, 0, BUFFER_LEN);
   eof = fseek(fp, -1024, SEEK_END);    //指向文件末尾 向前 偏移?量
   eof = fread(buf, 1024, 1, fp);
   fclose(fp);
   return eof;
}
int main(int argc, char **argv)
{
    int recvfd;
    struct sockaddr_in recvaddr;
    struct sockaddr_in sendaddr;
    unsigned char *buffer;
    unsigned char *tmpbuffer;
    int buffer_len;
    int recv_len;
    unsigned char recv_index;
    bzero(&recvaddr, sizeof(struct sockaddr_in)); 
    recvfd = socket(AF_INET, SOCK_DGRAM, 0);
    recvaddr.sin_family = AF_INET;
    recvaddr.sin_port = htons(LINTEN_PORT);
    recvaddr.sin_addr.s_addr = INADDR_ANY;

 printf("receving on port:%d\n", LINTEN_PORT);
  fflush(stdout);
     
    if (bind(recvfd, (struct sockaddr *)&recvaddr, sizeof(struct sockaddr)) < 0)
    {
        printf("Fail to bind\n");
    }


    buffer_len = BUFFER_LEN;
    recv_len = 0;    
    buffer = (unsigned char *)malloc(buffer_len);
    
    while (1)
    {
        fd_set readset;
        FD_ZERO(&readset);
        FD_SET(recvfd, &readset);
        struct timeval tv;
        tv.tv_sec = 5;
        tv.tv_usec = 0;


        int retval = select(recvfd+1, &readset, NULL, NULL, &tv);
        if (retval == -1)
        {
            printf("select error\n");
        }
        else if (retval)
        {
            int addr_len = sizeof(struct sockaddr_in);
            //printf("data arrive\n");           
            //printf("begin receive\n");
            memset(buffer, 0, buffer_len);
            recv_len = recvfrom(recvfd, buffer, buffer_len, 0,
                                (struct sockaddr *)&recvaddr,
                                (socklen_t *)&addr_len
                                );
            if (recv_len > 0 && recv_len == buffer_len)
            {
                //printf("receive data %d\n", recv_len);
                //printf("from ip:%s \n", inet_ntoa(recvaddr.sin_addr));
                //printf("recerve data:%s \n", buffer);
                char command[8];
                memset(command, 0, 8);
                memcpy(command, buffer, 6);
                if(strcmp(command, "config")==0)
                {
                     char configinfo[buffer_len];
                     memset(configinfo, 0, buffer_len);
                     memcpy(configinfo, buffer+6, buffer_len-6);
                     
                     //save config info to mtd
                     int ret = saveconfigx(configinfo);
                     ret = readconfigx(buffer);   
                     if(ret>0) printf("config ip:%s sucessfully! \n", buffer);                                                                          
                     sendMsg(inet_ntoa(recvaddr.sin_addr), LINTEN_PORT, "Success!");   
                } else if(strcmp(command, "findme")==0)
                {    
                     //printf("receive:%s \n", buffer);
                     readconfigx(buffer); 
                     
                     sendMsg(inet_ntoa(recvaddr.sin_addr), LINTEN_PORT, buffer); 
                }
                fflush(stdout);
            }                             
       }
        else
        {
            //printf("select timeout\n");
        }
        fflush(stdout);
    }  
    close(recvfd); 
    free(buffer);
    return 0;
}
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

ZHUJLFINE

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值