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;
}
分类: 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;
}