如何让多播报文从指定的网口发出去
来源:互联网 发布:单片机属于嵌入式吗 编辑:程序博客网 时间:2024/05/14 21:35
如果目的地址是multicast, 可以使用 socket 选项 IP_MULTICAST_IF,它指定多播报文是哪个网络接口发出去:
struct Ip_in_addr in_addr; /* for IP_IP_MULTICAST_IF */ struct sockaddr_in myAddr; /* for bind */ /* create client's socket */ if((sFd = socket(AF_INET, SOCK_DGRAM,0)) == ERROR ) { perror ("socket"); return (ERROR); } /* test IP_IP_MULTICAST_IF */ in_addr.s_addr = inet_addr(nic); /* interface address */ if (ipcom_setsockopt(sFd, IP_IPPROTO_IP, IP_IP_MULTICAST_IF, &in_addr, sizeof(in_addr)) < 0) { printf ("ipcom_setsockopt IP_IP_MULTICAST_IF failed, errno = %d\n", errno); }
这是我写的一个udp client 程序,在vxworks 下通过。 修改一下头文件,应该也可以在其它操作系统下编译和运行。
/* test if udp broadcast is OK *//* Dai Yuwen, December 2011 */#include <vxWorks.h>#include <sockLib.h>#include <inetLib.h>#include <hostLib.h>#include <string.h>#include <stdio.h>#include <ipcom_sock.h>#define SERVER_PORT_NUM 9#define REQUEST_MSG_SIZE 1024struct request { int display; char message[REQUEST_MSG_SIZE];};/* usage: udpClient serverIP, interfaceIP */STATUS udpClient(char *serverName, char* nic){ struct request myRequest; struct sockaddr_in serverAddr; int sockAddrSize; int sFd; int mlen; int addr; struct Ip_in_addr in_addr; /* for IP_IP_MULTICAST_IF */ struct sockaddr_in myAddr; /* for bind */ /* create client's socket */ if((sFd = socket(AF_INET, SOCK_DGRAM,0)) == ERROR ) { perror ("socket"); return (ERROR); } /* test IP_IP_MULTICAST_IF */ in_addr.s_addr = inet_addr(nic); /* interface address */ if (ipcom_setsockopt(sFd, IP_IPPROTO_IP, IP_IP_MULTICAST_IF, &in_addr, sizeof(in_addr)) < 0) { printf ("ipcom_setsockopt IP_IP_MULTICAST_IF failed, errno = %d\n", errno); } /* bind not required - port is dynamic */#if 1 bzero(&myAddr, sizeof(myAddr)); myAddr.sin_family = AF_INET; myAddr.sin_addr.s_addr = inet_addr(nic); /* interface address */ /*myAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* interface address */ myAddr.sin_port = 0; /* let kernel choose port */ if(bind(sFd, (struct sockaddr *)&myAddr, sizeof(myAddr)) < 0) { printf ("bind failed, errno = %d s_addr = %x\n", errno, myAddr.sin_addr.s_addr); }#endif /* bind server socket address */ sockAddrSize = sizeof(struct sockaddr_in); bzero((char*)&serverAddr, sockAddrSize); serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(SERVER_PORT_NUM);#if 0 if(((serverAddr.sin_addr.s_addr = inet_addr(serverName)) == ERROR )&& ((serverAddr.sin_addr.s_addr = hostGetByName(serverName)) == ERROR)) { perror ("unknown server name"); close(sFd); return (ERROR); } serverAddr.sin_addr.s_addr = hostGetByName(serverName); if (serverAddr.sin_addr.s_addr == ERROR){ perror ("unknown server name"); close(sFd); return (ERROR); }#endif addr = inet_addr(serverName); if (serverAddr.sin_addr.s_addr == ERROR){ perror ("unknown server name"); close(sFd); return (ERROR); } serverAddr.sin_addr.s_addr = addr; memcpy (myRequest.message, "greeting from vxworks", 21); if(sendto(sFd, (caddr_t)&myRequest, 0 /*sizeof(myRequest)*/, 0, (struct sockaddr *)&serverAddr, sockAddrSize) == ERROR) { perror ("sendto"); close(sFd); return(ERROR); } close(sFd); return(OK);}
用法是这样的:
-> udpClient "224.0.0.1","192.168.20.1" -> udpClient "224.0.0.1","172.25.52.31"
udpClient 的第二个参数指定的是网口地址,表示要从该网口出去。 在PC上抓
包,验证了这点。
另外,我还验证了调用bind是没有用的,虽然源IP地址按要求设置了, 但UDP包并不从
指定IP地址的那个口出去,这是符合预期的,因为到底从哪个口出去,由路由决
定,而查找路由是根据目的IP地址,跟源IP无关。
还有,有人想把广播包从指定网口发出去,用这个选项是没有用的。 只能加路由解决。
阅读全文
0 0
- 如何让多播报文从指定的网口发出去
- Spirent TestCenter查看发出的报文
- SDIO驱动(11)Host是如何把数据发出去的
- 一封不会发出去的信
- Wireshark 抓取本地发出去的数据包
- 一封没有发出去的信
- 一封没有发出去的信
- Notification发出指定的提示音
- 如何发出你的邮件
- 写上一笔,发出去
- 如何从TCP中提取HTTP报文
- 如何发出自己的光芒(顶)
- 如何从SEO的立场去设想网站URL
- 如何从优化的角度去选择CMS
- Linux中报文是如何从网卡传递到相应协议的
- [WebGL入门]二十一,从平行光源发出的光
- [WebGL入门]二十二,从环境光源发出的光
- 如何mock合作方的报文(报文可设置)
- JAVA IO系统 (笔记一)
- 渐进式框架-vue
- linux命令ps aux|grep xxx详解
- Struts2标签库整理【完整】
- [Unity][unet][Android]真机安卓和模拟器安卓发送信息交互通讯
- 如何让多播报文从指定的网口发出去
- Edittext设置inputType为密码不能生效
- 16.4 国际化的 URI
- android系统裁剪方法
- HTML 表格标签
- [CEOI2017]One-Way Streets
- 16.5 注意的问题
- 【坑】Firefox弹出 “Plugin Container for Firefox已停止工作” 处理办法。
- functionalInterface