socket中关于接收UDP协议码流的问题?

hyralist 2012-02-22 04:32:15
服务器是设置为自动输出UDP协议的码流的,我要在自己的PC上接收,用socket编,是不是用recvfrom()之前一定要

sendto()啊,我刚学这方面不太懂,因为服务器端(IP摄像机)它是通电插网线即可自动传输,那客户端这边的socket要进行

哪些必要的步骤啊?
...全文
190 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
hyralist 2012-02-24
  • 打赏
  • 举报
回复
问题搞定,是防火墙阻拦了组播包,关掉防火墙就可以接收了,非常感谢mayudong1(请叫我东哥)
mayudong1 2012-02-23
  • 打赏
  • 举报
回复
刚才看了一下,recvfrom中的那个地址参数是个输出参数

这样的话你的程序就需要绑定一个地址和端口了,绑定的端口是那个IP摄像机发送的端口
hyralist 2012-02-23
  • 打赏
  • 举报
回复
再问一下,我recvfrom()没反应,怎么判断到底接收到没啊?还是绑定自己的客户端有错误?不知道自己的IP和端口号怎么绑定加组播啊?
hyralist 2012-02-23
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 mayudong1 的回复:]
udp发送数据的时候需要知道对方的地址和端口,不需要绑定本机的端口
这样的话你看到的9001可能就是它所使用的端口,而不是它发送的目的端口

抓包工具应该可以看到一个包的源地址源端口和目的地址目的端口吧,你绑定的端口应该是它的目的端口
[/Quote]

应该是我本地套接字绑定的不是我自己的PC,我将自己的电脑与IP摄像机项链在抓包,抓不到显示自己pc的IP地址的包,也就没法看到端口,一直显示的事摄像机与另一个IP地址的连接。是不是我没成功加入组播,摄像机不和我的PC通信。
mayudong1 2012-02-23
  • 打赏
  • 举报
回复
udp发送数据的时候需要知道对方的地址和端口,不需要绑定本机的端口
这样的话你看到的9001可能就是它所使用的端口,而不是它发送的目的端口

抓包工具应该可以看到一个包的源地址源端口和目的地址目的端口吧,你绑定的端口应该是它的目的端口
hyralist 2012-02-23
  • 打赏
  • 举报
回复
不是,是很多包的,连接只有一个,记错了,不好意思。
hyralist 2012-02-23
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 mayudong1 的回复:]
socket不做设置的话应该是阻塞的,在接收操作时如果没有数据到来就会一直等下去

这里应该是recvfrom因为没有数据在一直等待数据

你应该确认一下组播地址和端口是不是你设置的那个,或者在你运行的时候它有没有发送数据
[/Quote]

组播地址如果是IP摄像机的IP地址和端口的话就肯定是的了,一方面对方提供的就是这个地址,另一方面我也用sniffer抓包,也查到是这个,还有抓包的时候,可以看到他的数据量很大的,几百兆bps,问题是他貌似是以流的形式传输的,我抓的就一个包,里面的数据都放在一起,很多。难不成UDP协议的套接字不支持?还是我自己客户端的地址绑定的不对,以至于收不到?
mayudong1 2012-02-23
  • 打赏
  • 举报
回复
socket不做设置的话应该是阻塞的,在接收操作时如果没有数据到来就会一直等下去

这里应该是recvfrom因为没有数据在一直等待数据

你应该确认一下组播地址和端口是不是你设置的那个,或者在你运行的时候它有没有发送数据
hyralist 2012-02-23
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 mayudong1 的回复:]
刚才看了一下,recvfrom中的那个地址参数是个输出参数

这样的话你的程序就需要绑定一个地址和端口了,绑定的端口是那个IP摄像机发送的端口
[/Quote]
下面是我改好的代码,但是调试的时候到了recvfrom()那里就不行了,我用单步调试,发现到了recvfrom()那里,小黄箭头就没了,下面的自动窗口什么的也消失了,这是怎么回事啊,我实在找不出原因,麻烦了!歇歇!

//客户端
#include <winsock2.h>
#include <stdio.h>
#include <windows.h>
#pragma comment(lib,"ws2_32.lib")
#include <tchar.h>
#include<ws2tcpip.h>

int main()
{
//初始化套接字
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
printf("初始化套接字失败!\n");
return -1;
}
printf("初始化套接字成功!\n");

//建立客户端SOCKET
SOCKET client;
client=socket(AF_INET,SOCK_DGRAM,0);
if(client==INVALID_SOCKET)
{
printf("建立客户端套接字失败; %d\n",WSAGetLastError());
WSACleanup();
return -1;
}
printf("建立客户端套接字成功!\n");
//绑定本地套接字
memset(&local,0,sizeof(sockaddr_in));
local.sin_family=AF_INET;
local.sin_addr.S_un.S_addr=INADDR_ANY;
local.sin_port=htons(9001);
int a=bind(client,(sockaddr*)&local,sizeof(sockaddr_in));
if(a==SOCKET_ERROR)
{
printf("bind failed:%d\n",WSAGetLastError());
closesocket(client);
}
printf("成功绑定套接字!\n");
//加入组播
struct ip_mreq mreq;
memset(&mreq,0,sizeof(struct ip_mreq));
mreq.imr_multiaddr.S_un.S_addr=inet_addr("224.168.00.01"); //组播源地址
mreq.imr_interface.S_un.S_addr=INADDR_ANY; //本地地址
int m=setsockopt(client,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char FAR *)&mreq,sizeof(mreq));
if(m==SOCKET_ERROR)
{
//perror("setsockopt");
printf("%d\n",WSAGetLastError());
return -1;
}
printf("加入组播成功!\n");

//接收数据
char recvbuf[1000000]; //回头注意重新设定缓冲区大小
int n;
DWORD dwWrite; //DWORD在windows下常用来保存地址(或者存放指针)
BOOL bRet;
int len=sizeof(sockaddr_in);



//创建文件
HANDLE hFile=CreateFile(_T("E:\\实验室\\YUV格式\\shipin.yuv"),GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
if(hFile!=INVALID_HANDLE_VALUE)
{
printf("创建文件成功!\n");
}

while(1)
{
n=recvfrom(client,recvbuf,sizeof(recvbuf),0,(sockaddr*)&serveraddress,&len);

if(n==SOCKET_ERROR)
{
printf("recvfrom error:%d\n",WSAGetLastError());
printf("接收数据错误!\n");

}
printf("正在接收数据。。。\n");

//将接收到的数据写到hFile中
bRet=WriteFile(hFile,recvbuf,n,&dwWrite,NULL);
if(bRet==FALSE)
{
MessageBox(NULL,_T("Write Buf ERROR!"),_T("ERROR"),MB_OK);
break;
}
}

//传送成功

MessageBox(NULL,_T("Receive file OK!"),_T("OK"),MB_OK);

closesocket(client);
WSACleanup();
return 0;
}

本地套接字绑定时端口是IP摄像机的端口,我用sniffer抓包找的,但也不知对不对。
hyralist 2012-02-22
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 visualeleven 的回复:]
UDP,你客户端创建好socket之后,直接接收数据就好了?你的UDP服务器是怎么写的?
[/Quote]
服务器是一个IP摄像机,貌似是自动发送数据的,不用操作吧。
hyralist 2012-02-22
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 mayudong1 的回复:]
应该是的,加入组播组好像用setsockopt函数设置的,具体用法可以百度一下
[/Quote]
好的,我先去看一下,先谢谢你了!
Eleven 2012-02-22
  • 打赏
  • 举报
回复
UDP,你客户端创建好socket之后,直接接收数据就好了?你的UDP服务器是怎么写的?
mayudong1 2012-02-22
  • 打赏
  • 举报
回复
应该是的,加入组播组好像用setsockopt函数设置的,具体用法可以百度一下
hyralist 2012-02-22
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 mayudong1 的回复:]
224.168.00.01
这是一个组播地址吧,接收的时候应该先加入到组播组中
[/Quote]
是加入组播就可以接收吗,其他还有什么注意事项吗?我刚开始学,不太懂?麻烦你指导了!
mayudong1 2012-02-22
  • 打赏
  • 举报
回复
224.168.00.01
这是一个组播地址吧,接收的时候应该先加入到组播组中
hyralist 2012-02-22
  • 打赏
  • 举报
回复
//客户端
#include <winsock2.h>
#include <stdio.h>
#include <windows.h>
#pragma comment(lib,"ws2_32.lib")
#include <tchar.h>

void main()
{
//初始化套接字
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
printf("初始化套接字失败!\n");
exit(-1);
}
printf("初始化套接字成功!\n");
//建立客户端SOCKET
SOCKET client;
client=socket(AF_INET,SOCK_DGRAM,0);
if(client==INVALID_SOCKET)
{
printf("建立客户端套接字失败!\n");
WSACleanup();
return;
}
printf("建立客户端套接字成功!\n");


sockaddr_in serveraddress;
memset(&serveraddress,0,sizeof(sockaddr_in));
serveraddress.sin_family=AF_INET;
serveraddress.sin_addr.S_un.S_addr=inet_addr("224.168.00.01");
serveraddress.sin_port=htons(9001);



//接收数据
char recvbuf[1000000]; //回头注意重新设定缓冲区大小
int m,n;
DWORD dwWrite; //DWORD在windows下常用来保存地址(或者存放指针)
BOOL bRet;
int len=sizeof(sockaddr_in);



//创建文件
HANDLE hFile=CreateFile(_T("E:\实验室\YUV格式\shipin.yuv"),GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
if(hFile!=INVALID_HANDLE_VALUE)
{
printf("创建文件成功!\n");
}

while(1)
{
n=recvfrom(client,recvbuf,sizeof(recvbuf),0,(sockaddr*)&serveraddress,&len);
if(n==SOCKET_ERROR)
{
WSAGetLastError();
printf("接收数据错误!\n");

}
//将接收到的数据写到hFile中
bRet=WriteFile(hFile,recvbuf,n,&dwWrite,NULL);
if(bRet==FALSE)
{
MessageBox(NULL,_T("Write Buf ERROR!"),_T("ERROR"),MB_OK);
break;
}
}

//传送成功

MessageBox(NULL,_T("Receive file OK!"),_T("OK"),MB_OK);

closesocket(client);
WSACleanup();
return;
}

能不能请高手帮看一下红色部分的接收直接这样写可不可以啊?
hyralist 2012-02-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 mayudong1 的回复:]
直接recvfrom就行,参数里面不是有地址吗,表示从哪里接收的
[/Quote]
我来试试看
hyralist 2012-02-22
  • 打赏
  • 举报
回复
[Quote=引用楼主 hyralist 的回复:]
服务器是设置为自动输出UDP协议的码流的,我要在自己的PC上接收,用socket编,是不是用recvfrom()之前一定要

sendto()啊,我刚学这方面不太懂,因为服务器端(IP摄像机)它是通电插网线即可自动传输,那客户端这边的socket要进行

哪些必要的步骤啊?
[/Quote]
我来试试看
mayudong1 2012-02-22
  • 打赏
  • 举报
回复
直接recvfrom就行,参数里面不是有地址吗,表示从哪里接收的

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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