- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试实现 SSDP 协议(protocol),但我不确定它到底是如何工作的。 SSDP通过udp发送数据,这是明确的。如果 Controller 连接到网络,它可以通过 MSEARCH 消息搜索设备,该消息可以发送到多播地址 239.255.255.250:1900。每个设备都必须监听该地址并做出响应。但我不知道他们如何回应。我在wireshark中看到它们以单播响应,但我不知道如何确定接收响应的端口。
编辑----------------
我正在尝试使用尖峰模糊测试框架编写 ssdp 模糊器。正如我所说,我能够发送正确的数据,但无法接收响应。我将尝试粘贴一些带有简短解释的尖峰代码。有 Spike 结构,它表示要发送的数据(它存储实际数据、大小、协议(protocol)信息...)。我删除了一些变量以使其更加清晰。
struct spike {
/*total size of all data*/
unsigned long datasize;
unsigned char *databuf;
unsigned char *endbuf;
int fd; /*for holding socket or file information*/
int proto; /*1 for tcp, 2 for udp*/
struct sockaddr_in *destsockaddr;
};
现在我通过 udp 发送数据,并希望通过以下函数接收一些响应
spike_connect_udp(target,port);
spike_send();
s_read_packet();
函数实现:
int
spike_connect_udp(char * host, int port)
{
int fd;
/*ahh, having udpstuff.c makes this stuff easy*/
fd=udpconnect(host,port);
if (fd==-1)
{
fprintf(stderr,"Couldn't udp connect to target\n");
return (0);
}
current_spike->fd=fd;
current_spike->proto=2; /*UDP*/
return 1;
}
int
udpconnect(const char * host, const unsigned short port )
{
int sfd = -1;
struct sockaddr_in addr;
/* Translate hostname from DNS or IP-address form */
memset(&addr, 0, sizeof(addr));
if (!getHostAddress(host, &addr))
{
hdebug("can't resolve host or address.\n");
return -1;
}
addr.sin_family = AF_INET;
addr.sin_port = ntohs(port);
if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
hdebug("Could not create socket!\n");
return -1;
}
/* Now connect! */
if (connect(sfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
close(sfd);
return -1;
}
return sfd;
}
int
spike_send()
{
int retval;
switch (current_spike->proto)
{
case 1: /*TCP*/
//deleted, doesnt matter, i am sending via udp
case 2: /*UDP*/
//udp_write_data is function from framework
retval=udp_write_data(current_spike->fd, current_spike->destsockaddr, s_get_size(), s_get_databuf());
break;
}
fflush(0);
return retval;
}
这工作正常并通过 udp 发送数据。现在我想通过打开套接字 current_spike->fd 接收一些响应。函数 s_read_packet无效
s_read_packet()
{
unsigned char buffer[5000];
int i;
int size;
s_fd_wait();
printf("Reading packet\n");
memset(buffer,0x00,sizeof(buffer));
/what alarm and fcntl does?
alarm(1);
fcntl(current_spike->fd, F_SETFL, O_NONBLOCK);
//this read return error -1 and sets errno to 11 service temporarily unavailable
size=read(current_spike->fd,buffer,1500);
fcntl(current_spike->fd, F_SETFL, 0);
alarm(0);
for (i=0; i<size; i++)
{
if (isprint(buffer[i]))
printf("%c",buffer[i]);
else
printf("[%2.2x]",buffer[i]);
}
printf("\nDone with read\n");
}
int
s_fd_wait()
{
/*this function does a select to wait for
input on the fd, and if there
is, returns 1, else 0 */
int fd;
fd_set rfds;
struct timeval tv;
int retval;
fd=current_spike->fd;
/* Watch server_fd (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
/* Wait up to zero seconds . will this wait forever? not on linux.*/
/* from man page: timeout is an upper bound on the amount of time
elapsed before select returns. It may be zero, causing select
to return immediately. If timeout is NULL (no timeout), select
can block indefinitely. */
/*wait 2 seconds only*/
tv.tv_sec = TIMEINSECONDS;
tv.tv_usec = TIMEINUSECONDS;
//printf("Before select %d:%d\n",TIMEINSECONDS,TIMEINUSECONDS);
retval = select(fd+1, &rfds, NULL, NULL, &tv);
/* Don't rely on the value of tv now! */
//printf("After select retval=%d.\n",retval);
switch (retval)
{
case 0:
/*Timeout - no packet or keypress*/
return(0);
break;
case -1:
/* ignore interrupted system calls */
if (errno != EINTR)
{
/*some kind of weird select error. Die. */
exit(-1);
}
/*otherwise we got interrupted, so just return false*/
return (0);
break;
default:
{
if (FD_ISSET(fd,&rfds))
return (1);
else
return (0);
}
}
}
但是函数 s_read_packet 没有产生数据...
最佳答案
为了实现 SSDP,您的应用程序需要能够将 NOTIFY
和 M-SEARCH
header 发送到指定的多播地址,并且还应该能够接收这些消息。为此,您需要创建一个专门的 UDP 套接字。
以下是如何初始化此类套接字的示例:
// Structs needed
struct in_addr localInterface;
struct sockaddr_in groupSock;
struct sockaddr_in localSock;
struct ip_mreq group;
// Create the Socket
int udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
// Enable SO_REUSEADDR to allow multiple instances of this application to receive copies of the multicast datagrams.
int reuse = 1;
setsockopt(udpSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));
// Initialize the group sockaddr structure with a group address of 239.255.255.250 and port 1900.
memset((char *) &groupSock, 0, sizeof(groupSock));
groupSock.sin_family = AF_INET;
groupSock.sin_addr.s_addr = inet_addr("239.255.255.250");
groupSock.sin_port = htons(1900);
// Disable loopback so you do not receive your own datagrams.
char loopch = 0;
setsockopt(udpSocket, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopch, sizeof(loopch));
// Set local interface for outbound multicast datagrams. The IP address specified must be associated with a local, multicast capable interface.
localInterface.s_addr = inet_addr("192.168.0.1");
setsockopt(udpSocket, IPPROTO_IP, IP_MULTICAST_IF, (char *)&localInterface, sizeof(localInterface));
// Bind to the proper port number with the IP address specified as INADDR_ANY.
memset((char *) &localSock, 0, sizeof(localSock));
localSock.sin_family = AF_INET;
localSock.sin_port = htons(1900);
localSock.sin_addr.s_addr = INADDR_ANY;
bind(udpSocket, (struct sockaddr*)&localSock, sizeof(localSock));
// Join the multicast group on the local interface. Note that this IP_ADD_MEMBERSHIP option must be called for each local interface over which the multicast datagrams are to be received.
group.imr_multiaddr.s_addr = inet_addr("239.255.255.250");
group.imr_interface.s_addr = inet_addr("192.168.0.1");
setsockopt(udpSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group));
现在您可以使用此套接字将数据发送到多播组:
sendto(udpSocket, message, message_length, 0, (struct sockaddr*)&groupSock, sizeof(groupSock));
要接收消息,请执行以下操作:
struct sockaddr_in si_other;
socklen_t slen = sizeof(si_other);
char buffer[1024];
recvfrom(udpSocket, buffer, 1024, 0, (struct sockaddr *) &si_other, &slen);
要响应特定请求(如上所述收到),请执行以下操作:
sendto(udpSocket, message, message_length, 0, (struct sockaddr*)&si_other, sizeof(si_other));
您现在要做的就是创建发送所需的消息并处理接收到的数据。假设您向多播组发送 M-SEARCH
请求(如上所述),那么您将从每个设备获得如下响应:
HTTP/1.1 200 OK
SERVER: Linux/2.6.15.2 UPnP/1.0 Mediaserver/1.0
CACHE-CONTROL: max-age=1200
LOCATION: http://192.168.0.223:5001/description.xml
ST: urn:schemas-upnp-org:device:MediaServer:4
USN: uuid:550e8400-e29b-11d4-a716-446655440000::urn:schemas-upnp-org:device:MediaServer:4
Content-Length: 0
EXT:
关于SSDP协议(protocol)-实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13382469/
我需要能够发送 UDP 消息并接收消息,以便从 iPhone 发现网络上的 SSDP 设备。 我知道我需要将数据包发送到多播地址,并且我的 HTTP 请求需要如下所示: M-SEARCH * HTTP
我创建了一个简单的 Android 应用程序来扫描我的本地网络;我已将 M-SEARCH 用于此搜索目标: String sentence = "M-SEARCH * HTTP/1.1\r\n"
我经常用谷歌搜索这个问题,但对于我到底想做什么是否可行仍然有点困惑。 基本上,我正在尝试向我的 Web 应用程序添加一个下拉菜单,其中列出了连接到网络的所有设备。当我说设备时,我并不是在谈论所有设备;
这个服务现在用到是非常少的,小编建议大家改为手动使用,这样当我们需要使用它的时候也能使用它,如果你电脑发现这个服务对应的svchost.exe进程使用的CPU非常,可以关闭它,但是不建议直接永久禁用
我希望有人能澄清我对 upnp/ssdp 使用的 NOTIFY 和 M-SEARCH 消息的目的背后的困惑。协议(protocol)。 我的理解是,当设备想要向其他支持 UPNP 的设备宣传自己时会发
我正在实现一个应该响应 SSDP 的设备M-SEARCH查询。 我是设备供应商,我无法控制这些设备的部署位置。 有一种已知的 DDoS 攻击使用 SSDP 搜索放大,即攻击者从虚假地址发送搜索请求,而
我正在尝试进行 SSDP 发现广播,但无法从 NWConnection.receive 获取回复数据。 Network.framework 相对较新,没有太多信息。我在这里缺少什么? SSDP 发现广
我已经在我的 NodeMCU 上运行了 ESP8266SSDP 库,并将其配置如下: SSDP.setSchemaURL("test.xml"); SSDP.setHTTPPort(80); SSDP
我想在网络上搜索我的媒体播放器。我认为它是使用 SSDP m-search 完成的吗? 另外,当我打开设备时,它会广播它的可用性吗?如何收听该广播,以及如何发送 m-search 查询? 最佳答案 I
我正在尝试收听 SSDP 多播消息,例如 NOTIFY 和 SEARCH。 这是我的代码,但我没有看到这些消息,即使 wireshark 看到了它们。那么,如何加入SSDP多播组并接收消息呢? Reb
我正在尝试测试以下 Cordova 插件中存在的 SSDP 实现: https://github.com/fraunhoferfokus/cordova-plugin-hbbtv/tree/maste
我正在使用 SSDP 发送发现请求,使用 M-SEARCH 获取存在的服务列表。我的要求就像我想获得该服务器中也存在的共享文件夹列表。 目前,我正在以这种格式发送此请求: "M-SEARCH * HT
我正在尝试在我的安卓应用中实现一个非常简单的 SSDP 功能 from here . 我的应用程序毫无问题地向广播地址发送了一些包含相关 M-SEARCH 消息的 UDP 数据包。问题是,我应该从其他
我正在尝试创建一个类似 Chromecast 的设备,可以从互联网流式传输视频并进行远程控制。我使用 HTTP get 请求对设备进行远程控制,并使用以下代码监听它们: 监听对设备的 HTTP 请求(
当发出 M-SEARCH 命令时,所有提供服务的设备都必须回复它们提供的服务的 IP 地址。 我的手机有 2 个接口(interface)(除其他外): 192.168.1.5:wifi接口(inte
长话短说:SSDP library没有收到数据报。 Wireshark 显示预期的(?)流量。 我正在使用 android-dlna library在 Android 应用程序中支持 SSDP。目标是
SSDP M搜索发现请求非常适合多播地址239.255.255.250。但是,我有一个要求将此请求发送到特定IP。这没用。根据UPnP architecture document支持单播发现消息,与多
我实现了 discovery using SSDP在我的 Windows 8 应用程序中,一切都很好。我昨天更新到 8.1,现在发现不再有效。现在,当我调用 await socket.GetOutpu
我正在尝试使用 C#Windows 应用商店 应用程序实现基本的 SSDP (UDP) 广播/监听器 em>. 我发现 Windows.Networking.Sockets包含 DatagramSoc
这个问题让我发疯了一段时间。由于我从来没有做过任何网络相关的代码,所以我无法得出这个实验的结果。 我获得了有关使用 SSDP 广播相关信息的服务器的信息。我按照标准获得了 IP 和端口。我还获得了需要
我是一名优秀的程序员,十分优秀!