ssdp协议获取局域网设备 求大神或者做过的人指点!

mikeconan 2017-08-22 06:14:56
不多说直接上代码!

int ReceiveData(int socket, char * data, int length, int timeout)
{
int n;
fd_set socketSet;
struct timeval timeval;
FD_ZERO(&socketSet);
FD_SET(socket, &socketSet);
timeval.tv_sec = timeout / 1000;
timeval.tv_usec = (timeout % 1000) * 1000;
n = select(socket + 1, &socketSet, NULL, NULL, &timeval);
if (n < 0) {
printf("select");
return -1;
}
else if (n == 0) {
return 0;
}
n = recv(socket, data, length, 0);
if (n < 0) {
printf("recv");
}
return n;
}

//发广播包
SArray<string> UpnpTool::upnpDiscover(int delay, const char * multicastif)
{
SArray<string> devlist;
WSADATA wsaData;
int opt = 1;
static const char MSearchMsgFmt[] = "M-SEARCH * HTTP/1.1\r\n HOST: 239.255.255.250:1900\r\n ST: %s\r\n MAN: ssdp:discover\r\n MX: 3\r\n\r\n";

char bufr[1536]; /* reception and emission buffer */
int sudp;
int n;
struct sockaddr_in sockudp_r, sockudp_w;

if (WSAStartup(MAKEWORD(2, 0), &wsaData) == SOCKET_ERROR){
return devlist;
}

sudp = socket(AF_INET, SOCK_DGRAM, 0);
if (sudp < 0)
{
WSACleanup();
return devlist;
}
memset(&sockudp_r, 0, sizeof(struct sockaddr_in));//
sockudp_r.sin_family = AF_INET;
sockudp_r.sin_port = htons(65364);
sockudp_r.sin_addr.s_addr = inet_addr("192.168.168.133");

memset(&sockudp_w, 0, sizeof(struct sockaddr_in));
sockudp_w.sin_family = AF_INET;
sockudp_w.sin_port = htons(PORT);
sockudp_w.sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR); //htonl(INADDR_BROADCAST)

if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(int)) < 0)
{
goto failed;
}
opt = 1;
if (setsockopt(sudp, SOL_SOCKET, SO_BROADCAST, (const char *)&opt, sizeof(int)) < 0)
{
goto failed;
}

if (multicastif)
{
struct in_addr mc_if;
mc_if.s_addr = inet_addr(multicastif);
sockudp_r.sin_addr.s_addr = mc_if.s_addr;
if (setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
{
goto failed;
}
}
if (bind(sudp, (struct sockaddr*)&sockudp_r, sizeof(struct sockaddr_in)) != 0) {
goto failed;
}
int trynum = 1;
while (trynum > 0) {
SLOGFMTE("剩余尝试次数%d \n", trynum);
/* sending the SSDP M-SEARCH packet */
sprintf(bufr, MSearchMsgFmt, "urn:schem-as-upnp-org:device:MediaServer:"); // //ssdp:all
sockudp_w.sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
n = sendto(sudp, bufr, strlen(bufr), 0, (struct sockaddr*)&sockudp_w, sizeof(struct sockaddr_in));
if (n < 0) {
goto failed;
}
sockudp_w.sin_addr.s_addr = htonl(INADDR_BROADCAST);
n = sendto(sudp, bufr, strlen(bufr), 0, (struct sockaddr*)&sockudp_w, sizeof(struct sockaddr_in));

if (n < 0) {
SLOGFMTE("Find upnp device broadcast fail!");
}
do
{
//memset(bufr, 0, sizeof(bufr));
int ret = recvfrom(sudp, bufr, sizeof(bufr), 0, (struct sockaddr*)&sockudp_r, (socklen_t*)&sockudp_r);
n = ReceiveData(sudp, bufr, sizeof(bufr), delay);
if (n > 0) {
bufr[n] = 0;
SLOGFMTE("%s", bufr);
string deviceString = bufr;
if (!deviceString.empty())
{
devlist.Add(deviceString);
}
}
} while (n > 0);
trynum--;
// usleep(600);
}
failed:
closesocket(sudp);
WSACleanup();
return devlist;
}

没有响应,直接抓包,也没有发送出去,哪位看下,哪里错了!
...全文
1052 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
林兴南 2019-12-12
  • 打赏
  • 举报
回复
大佬,有没有关于设备发现的资料 给点
tf_ace 2019-06-21
  • 打赏
  • 举报
回复
假设我局域网内有两台PC(win10)分别为A和B,我用A以编码方式向组播地址发送search消息,B设备(ssdp discover 服务开启)收到后是否会自动回应A的消息? 我测试过程中发现,A没有收到B回复search的消息;打开B的媒体流选项并启用媒体流后,A才能收到B的回复,这是为什么?
mikeconan 2017-08-23
  • 打赏
  • 举报
回复
我只要一个简单的例子,你这个还包括服务端的,还用了boost 库,与我想要的相差很远啊!
mikeconan 2017-08-23
  • 打赏
  • 举报
回复
终于解决问题了!知道哪里错了!

5,530

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 模式及实现
社区管理员
  • 模式及实现社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧