首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

udp为什么收不到广播中的数据,该怎么处理

2012-03-04 
udp为什么收不到广播中的数据C/C++ codechar t_chMessage[DSC_DATASIZE] {0}SOCKET t_SocketSOCKADDR_

udp为什么收不到广播中的数据

C/C++ code
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_BROADCASTBOOL 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);


[解决办法]
sender 

C/C++ code
#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 objectCWinApp 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;} 


[解决办法]
如果网络中两个主机上的应用程序要相互通信,其一要知道彼此的IP,其二要知道程序可监听的端口。因为同一主机上的程序使用网络是通过端口号来区分的。

UDP Socket的使用过程:
1. 初始化网络库

2. 创建SOCK_DGRAM类型的Socket。

3. 绑定套接字。

4. 发送、接收数据。

5. 销毁套接字。

6. 释放网络库。

广播数据包的原理:
专门用于同时向网络中所有工作站进行发送的一个地址叫做广播地址。在使用TCP/IP 协议的网络中,主机标识段host ID 为全1 的IP 地址为广播地址。如果你的IP为:192.168.1.39,子网掩码为:255.255.255.0,则广播地址为:192.168.1.255;如果IP为192.168.1.39,子网掩码为:255.255.255.192,则广播地址为:192.168.1.63。

如果只想在本网络内广播数据,只要向广播地址发送数据包即可,这种数据包可以被路由,它会经由路由器到达本网段内的所有主机,此种广播也叫直接广播;如果想在整个网络中广播数据,要向255.255.255.255发送数据包,这种数据包不会被路由,它只能到达本物理网络中的所有主机,此种广播叫有限广播。

使用UDP协议发送、接收广播包的过程。
假如我们要向192.168.0.X,子网掩码为:255.255.255.0的子网中发送广播包。

其步骤如下:

1. 初始化Winsock库。

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;
}


热点排行