udp为什么收不到广播中的数据
本帖最后由 reage_wang 于 2011-05-04 19:54:04 编辑
char t_chMessage[DSC_DATASIZE] = {0};
SOCKET t_Socket;
SOCKADDR_IN t_SocketAddrIn;
SOCKADDR_IN t_SocketRemoteAddrIn;
int t_nRemoteAddrLen = 0;
int t_nRet = 0;
t_nRemoteAddrLen = sizeof(SOCKADDR_IN);
//设置为SO_BROADCAST
BOOL t_bBroadcast = TRUE;
//非阻塞模式设定
int t_nMode = 1;
t_SocketAddrIn.sin_family = AF_INET;
t_SocketAddrIn.sin_port = htons(1092);
t_SocketAddrIn.sin_addr.s_addr = htonl(INADDR_ANY);
t_SocketRemoteAddrIn.sin_family = AF_INET;
t_SocketRemoteAddrIn.sin_port = htons(1092);
t_SocketRemoteAddrIn.sin_addr.s_addr = htonl(INADDR_BROADCAST);
t_Socket = socket(AF_INET, SOCK_DGRAM, 0);
if(t_Socket == SOCKET_ERROR)
{
return 0;
}
t_nRet = setsockopt(t_Socket,SOL_SOCKET,SO_BROADCAST,(char*)&t_bBroadcast,sizeof(BOOL));
if (t_nRet != 0)
{
t_nRet = WSAGetLastError();
closesocket(t_Socket);
return 0;
}
t_nRet = ioctlsocket(t_Socket, FIONBIO, (u_long FAR*)&t_nMode);
if(t_nRet != 0)
{
t_nRet = WSAGetLastError();
closesocket(t_Socket);
return 0;
}
t_nRet = bind(t_Socket, (struct sockaddr*)&t_SocketAddrIn, sizeof(SOCKADDR_IN));
if(t_nRet == SOCKET_ERROR)
{
t_nRet = WSAGetLastError();
closesocket(t_Socket);
return 0;
}
fd_set fdRead;
struct timeval tv = {5,0};
while(true)
{
FD_ZERO(&fdRead);
FD_SET(t_Socket, &fdRead);
t_nRet = select(0, &fdRead, NULL, NULL, &tv);
if(t_nRet == 0)
{
continue;
}
else if(t_nRet < 0)
{
return 0;
}
if(FD_ISSET(t_Socket, &fdRead))
{
t_nRet = recvfrom(t_Socket, t_chMessage, DSC_DATASIZE, 0, (struct sockaddr *)&t_SocketRemoteAddrIn, &t_nRemoteAddrLen);
if(t_nRet == SOCKET_ERROR )
{
t_nRet = WSAGetLastError();
closesocket(t_Socket);
return 0;
}
else
{
t_chMessage[t_nRet] = '\0';
break;
}
}
}
closesocket(t_Socket);
谁能帮我看看这段代码有什么问题没?我这段代码怎么也收不到255.255.255.255广播的数据。
下面是我发送到广播中的代码。
int t_nRet = 0;
SOCKET t_Socket = NULL;
SOCKADDR_IN t_SocketAddrin;
BOOL t_bBroadcast = TRUE;
t_SocketAddrin.sin_family = AF_INET;
t_SocketAddrin.sin_port = htons(1092);
t_SocketAddrin.sin_addr.s_addr = inet_addr("255.255.255.255");
char t_chMessage[113] ={这里面是数据};
t_Socket = socket(AF_INET, SOCK_DGRAM, 0);
if(t_Socket == SOCKET_ERROR)
{
return;
}
//发送广播包
t_nRet = setsockopt(t_Socket,SOL_SOCKET,SO_BROADCAST,(const char*)&t_bBroadcast,sizeof(BOOL));
if(t_nRet != 0)
{
closesocket(t_Socket);
return;
}
sendto(t_Socket, t_chMessage, 113, 0, (struct sockaddr*)&t_SocketAddrin, sizeof(t_SocketAddrin));
closesocket(t_Socket);
#include "stdafx.h"
#include "sender.h"
#include <afxsock.h>
#include <shlwapi.h>
#pragma comment(lib, "shlwapi")
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// The one and only application object
CWinApp theApp;
using namespace std;
DWORD AFX_CDECL BoardcastSendProc(LPVOID pObject)
{
WSAData wd;
AfxSocketInit(&wd);
HANDLE stopEvent = (HANDLE)pObject;
CSocket senderSocket;
//会自己调用bind函数
senderSocket.Create(
0,//bind时候,自动调用了htons
SOCK_DGRAM, _T("127.0.0.1"));
int boradcast = true;
senderSocket.SetSockOpt(SO_BROADCAST, &boradcast, sizeof(boradcast), SOL_SOCKET);
sockaddr_in remoteAddress;
remoteAddress.sin_family = AF_INET;
remoteAddress.sin_addr.S_un.S_addr = INADDR_BROADCAST;
remoteAddress.sin_port = htons(8888);
LPTSTR pStrMessage = _T("this is a test for boardcast\r\n sender in:{%S}");
tm *newTime;
time_t szClock;
TCHAR buf[512] = { 0 };
while (::WaitForSingleObject(stopEvent, 1000) != WAIT_OBJECT_0)
{
// Get time in seconds
time( &szClock );
// Convert time to struct tm form
newTime = localtime( &szClock );
wnsprintf(buf, 512, pStrMessage, asctime( newTime ));
senderSocket.SendTo(buf, (_tcslen(buf)+1)*sizeof(buf[0]), (SOCKADDR*)&remoteAddress, sizeof(remoteAddress), 0);
}
//通知对方关闭
senderSocket.SendTo(NULL, 0, (SOCKADDR*)&remoteAddress, sizeof(remoteAddress), 0);
senderSocket.Close();
CloseHandle(stopEvent);
return 0;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
HANDLE stopEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
CWinThread* pThread = AfxBeginThread((AFX_THREADPROC)BoardcastSendProc, stopEvent);
while (true)
{
printf("enter letter('q') to quit \n");
if(tolower(getchar()) == 'q')
{
SetEvent(stopEvent);
break;
}
}
pThread->Delete();
}
return nRetCode;
}
// receiver.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "receiver.h"
#include <afxsock.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// The one and only application object
CWinApp theApp;
using namespace std;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
#define MAX_PACKET_SIZE (512)
WSAData wd;
AfxSocketInit(&wd);
// TODO: code your application's behavior here.
CSocket receiveSocket;
receiveSocket.Create(
8888,//bind时候,自动调用了htons
SOCK_DGRAM,
NULL/*表示绑定到INADDR_ANY*/);
while(true)
{
TCHAR buf[MAX_PACKET_SIZE]={0};
sockaddr_in senderAddress;
int senderAddressLength = sizeof(senderAddress);
int received = receiveSocket.ReceiveFrom(buf, MAX_PACKET_SIZE*sizeof(TCHAR), (SOCKADDR*)&senderAddress, &senderAddressLength, 0);
if (received != 0)
{
wprintf(_T("ReceiveFrom:%S Port:%d PacketSize:%d Message:%s \n"), inet_ntoa(senderAddress.sin_addr), ntohs(senderAddress.sin_port), received, buf);
}
else
{
receiveSocket.Close();
break;
}
}
}
return nRetCode;
}
2. 创建SOCK_DIRAM类型的Socket。
3. 设置Socket的属性允许其广播。
4. 发送数据包到192.168.0.255
5. 接收自己广播的广播包。
6. 关闭Socket
7. 释放网络库。
注意事项如下:
1. 接收方一定要知道广播方的口号,然后绑定此端口号才能正确接收。
2. 接收方的Socket不需要设置成广播属性。
3. 绑定的IP不可以使用“127.0.0.1”,可以使用真实IP地址或者INADDR_ANY。否则接收失败。
参考代码:
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
//*-----------变量,数据类型宏定义-------------------
#define PORT 3387
#define MAX 255
int main(void)
{
int sockfd, ret;
int size, len;
int so_broadcast=1;
struct sockaddr_in my_con;
struct sockaddr_in cl_con;
char snd[MAX] = "123456789";
char rec[MAX];
//创建socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd < 0)
{
perror("socket error!\n");
exit(1);
}
//创建套接口
my_con.sin_family = AF_INET;
my_con.sin_port = ntohs(PORT);
my_con.sin_addr.s_addr = inet_addr("192.168.1.255");
len = sizeof(struct sockaddr);
setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&so_broadcast,sizeof(so_broadcast));
//绑定套接口
if(bind(sockfd, (struct sockaddr *) &my_con, len) < 0)
{
perror("bind error!\n");
exit(1);
}
//数据传输处理
ret = sendto(sockfd, snd, strlen(snd), 0, (struct sockaddr *) &my_con, len);
if(ret < 0)
{
perror("send error!\n");
exit(1);
}
printf("发送广播数据:%s\n",snd);
size=sizeof(cl_con);
ret = recvfrom(sockfd,rec,MAX,0,(struct sockaddr *)&cl_con,&size);
rec[ret] = '\0';
printf("接收广播数据:%s\n",rec);
close(sockfd);
return 0;
}