[英]Unable to send UDP to a multicast group from a linux computer
I am trying to send a UDP-datagram to an IP camera from a computer running on Linux in order to discover it. 我正在尝试从Linux上运行的计算机向IP摄像机发送UDP数据报以便发现它。 All devices are connected via a switch.
所有设备都通过开关连接。
There is a windows app that is compatible with this camera, that sends out a UDP datagram to a multicast group and gets an answer from the camera via the same group. 有一个与此摄像头兼容的Windows应用程序,该应用程序将UDP数据报发送到多播组,并通过同一组从摄像头获取答案。 I found out this via Wireshark and decided to try and send the same datagram from a C program on my Linux machine.
我通过Wireshark发现了这一点,并决定尝试从Linux机器上的C程序发送相同的数据报。 I am able to get the correct response if my C program sends it directly to the camera's IP-address, but not if I send it to the multicast group.
如果我的C程序将其直接发送到摄像机的IP地址,则能够得到正确的响应,但是如果将其发送到多播组,则无法获得正确的响应。
I therefor made a listener program on my Linux computer and tried to send it to the multicast address. 为此,我在Linux计算机上制作了一个侦听器程序,并尝试将其发送到多播地址。 This succeeded, but I did not catch anything in Wireshark.
这成功了,但是我在Wireshark中什么也没发现。
So it seems that my C-program is able to send the datagram correctly, just not out on to the network. 因此,看来我的C程序能够正确发送数据报,只是无法发送到网络上。 Can this be some kind of Linux configuration?
这可以是某种Linux配置吗?
EDIT: As requested, here is the code. 编辑:根据要求,这是代码。 FYI: As of now, I am only trying to send data to the camera and examine the response in Wireshark.
仅供参考:到目前为止,我仅尝试将数据发送到相机并检查Wireshark中的响应。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
#include "udp_socket.h"
int main( void )
{
//int s = udp_socket(50000);
int s = socket(AF_INET,SOCK_DGRAM,0);
printf("Socket: %d\r\n", s);
char buffer[48] = {0x67,0x45,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x67,0x45,0x00,0x00,0x14,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0xea,0xc8,0xc8,0xc8,0xf4,0xe6,0x00,0x00};
struct sockaddr_in serveraddr;
memset( &serveraddr, 0, sizeof(serveraddr) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons( 59125 );
serveraddr.sin_addr.s_addr = inet_addr("234.200.200.200");
udp_socket_tx(s, buffer, sizeof(buffer), &serveraddr );
close(s);
}
udp_socket_tx() from udp_socket.h: 来自udp_socket.h的udp_socket_tx():
int udp_socket_tx(int socket_fd, char * tx_buffer, int tx_buffer_len, const struct sockaddr_in * to_addr) {
return sendto(
socket_fd,
tx_buffer,
tx_buffer_len,
0,
(const struct sockaddr *)to_addr,
sizeof(struct sockaddr_in)
);
}
The following proposed code: 建议的代码如下:
sendto()
. sendto()
调用的返回状态。 socket()
. socket()
的调用返回的状态。 #include
for the call to printf()
. #include
添加到对printf()
的调用中。 #include
for the call to memset()
. #include
添加到memset()
的调用中。 stderr
stderr
and now the proposed code: 现在建议的代码:
#include <stdio.h> // perror(), printf()
#include <stdlib.h> // exit(), EXIT_FAILURE, EXIT_SUCCESS
#include <string.h> // memset()
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
int main( void )
{
int s = socket(AF_INET,SOCK_DGRAM,0);
if ( 0 > s )
{
perror( "socket failed" );
exit( EXIT_FAILURE );
}
// implied else, socket successful
printf("Socket: %d\r\n", s);
unsigned char buffer[] =
{
0x67, 0x45,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x00,
0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00, 0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x67,0x45,
0x00, 0x00,0x14,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,
0xea, 0xc8, 0xc8, 0xc8, 0xf4, 0xe6, 0x00, 0x00
};
struct sockaddr_in serveraddr;
memset( &serveraddr, 0, sizeof(serveraddr) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons( 59125 );
serveraddr.sin_addr.s_addr = inet_addr("234.200.200.200");
ssize_t sendtoStatus = sendto
(
s,
buffer,
sizeof(buffer),
0,
(const struct sockaddr *)&serveraddr,
sizeof(struct sockaddr_in)
);
if( -1 == sendtoStatus )
{
perror( "sendto failed" );
close(s);
exit( EXIT_FAILURE );
}
close(s);
return EXIT_SUCCESS;
} // end function: main
When sending multicast datagrams, they will normally be sent out on whichever network interface is considered the default interface. 发送多播数据报时,通常会在被视为默认接口的任何网络接口上将其发送出去。
If that's not the interface you want to send on, you need to configure the outgoing multicast interface. 如果那不是您要发送的接口,则需要配置传出多播接口。 This is done with the
IP_MULTICAST_IF
option: 这是通过
IP_MULTICAST_IF
选项完成的:
If for example you want to send multicast from the interface with IP 192.168.1.1, you set it up as follows: 例如,如果要从IP为192.168.1.1的接口发送多播,请按以下步骤进行设置:
struct in_addr multi_interface;
multi_interface.s_addr = inet_addr("192.168.1.1");
if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF,
(char *)&multi_interface, sizeof(multi_interface)) == -1) {
perror("Error setting outgoing interface");
close(s);
exit(1);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.