这是一个IP多播的源程序,为什么到我这里就出问题呢?
一点开始就出
Memo1
加入组失败!代码:10049
这个错误!郁闷死了
我网卡已连接IP地址为192.168.0.1,系统是XP系统~我按照书上抄下来的,不知道为什么工作不了!
高手来看看咯!
端口设置为:1600实际上不管设置为什么都出这个问题!
//---------------------------------------------------------------------------
#include <vcl.h>
#include "winsock2.h"
#include "windows.h"
#include "ws2tcpip.h"
#pragma hdrstop
#pragma comment(lib,"ws2_32.lib")
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
/*********************************************************************/
#define BUFSIZE 1024
DWORD dwInterface,dwMulticastGroup,dwCount;
bool bSender=false;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
WSADATA wsd;
struct sockaddr_in local,remote,from;
SOCKET sock,sockm;
TCHAR recvbuf[1024],sendbuf[1024];
int len=sizeof(struct sockaddr_in),optval,ret;
short ports;
DWORD i=50;
dwInterface=inet_addr("192.168.0.1");
dwMulticastGroup=inet_addr("192.168.0.3");
dwCount=StrToInt(Edit1->Text);
ports=StrToInt(Edit2->Text);
if (WSAStartup(MAKEWORD(2,2),&wsd)!=0)
{
ShowMessage("WSAStartup()初始化失败!");
return;
}
if((sock=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF|WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)
{
ShowMessage("创建Socket失败(WSASocket)");
WSACleanup();
return;
}
local.sin_family=AF_INET;
local.sin_port =htons(ports);
local.sin_addr.s_addr=dwInterface;
if(bind(sock,(struct sockaddr *)&local,sizeof(local))==SOCKET_ERROR)
{
ShowMessage("Bind Socket失败(bind),失败代码:"+IntToStr(WSAGetLastError()));
WSACleanup();
return;
}
//-------------------建立多播组描述
remote.sin_family =AF_INET;
remote.sin_port=htons(ports);
remote.sin_addr.s_addr=dwMulticastGroup;
optval=8;
if(setsockopt(sock,IPPROTO_IP,IP_MULTICAST_TTL,(char*)&optval,sizeof(int))==SOCKET_ERROR)
{
ShowMessage("setsockopt(IP_MULTICAST_TTL)失败。代码:"+IntToStr(WSAGetLastError()));
WSACleanup();
return;
}
if((sockm=WSAJoinLeaf(sock,(SOCKADDR *)&remote,sizeof(remote),NULL,NULL,NULL,NULL,JL_BOTH))==INVALID_SOCKET)
{
Memo1->Lines->Add("加入组失败!代码:"+IntToStr(WSAGetLastError()));
closesocket(sock);
WSACleanup();
return;
}
if(!bSender)
{
for(i=0;i<dwCount;i++)
{
if((ret=recvfrom(sock,recvbuf,BUFSIZE,0,(struct sockaddr*)&from,&len))==SOCKET_ERROR)
{
ShowMessage("接收数据失败。代码:"+IntToStr(WSAGetLastError()));
WSACleanup();
return;
}
recvbuf[ret]=0;
AnsiString temp11;
temp11=recvbuf;
Memo1->Lines->Add("数据:"+temp11+"来自:"+inet_ntoa(from.sin_addr));
}
}
else
{
for(i=0;i<dwCount;i++)
{
Memo1->Lines->Add("发送数据:这是第"+IntToStr(i)+"个数据报");
sprintf(sendbuf,"发送数据:这是第%d个数据报",i);
if(sendto(sock,(char *)sendbuf,strlen(sendbuf),0,(struct sockaddr *)&remote,sizeof(remote))==SOCKET_ERROR)
{
ShowMessage("发送数据失败。代码:"+IntToStr(WSAGetLastError()));
WSACleanup();
return;
}
Sleep(500);
}
}
closesocket(sock);
WSACleanup();
return;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
if(Rb1->Checked ==true)
bSender=true;
else
bSender=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Rb1Click(TObject *Sender)
{
if(Rb1->Checked ==true)
bSender=true;
else
bSender=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Rb2Click(TObject *Sender)
{
if(Rb1->Checked ==true)
bSender=true;
else
bSender=false;
}
//---------------------------------------------------------------------------
问题点数:0、回复次数:5Top
1 楼xpdavis(咕嘟-不想孤独)回复于 2004-12-04 09:58:04 得分 0
没用过WSAJoinLeaf这个函数,不过请看下面这行代码:
dwMulticastGroup=inet_addr("192.168.0.3");
192.168.0.3是保留/私有地址,怎么可能作为多播/组播地址呢?我们知道多播/组播地址是从224.0.0.0-239.255.255.255的,其中有一部分已经分配做路由协议或者其它用途,239段是其中未分配的。楼主可以查阅相关资料获得多播/组播地址的信息。
这个是我以前写的代码片段,调试成功通过
ip_mreq FAddress;
FAddress.imr_interface.s_addr = INADDR_ANY;
FAddress.imr_multiaddr.s_addr = inet_addr("239.255.193.250");
setsockopt(FSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&FAddress, sizeof(ip_mreq));
Top
2 楼lswhome(Microsoft Visual C++6.0初学者)回复于 2004-12-04 17:51:21 得分 0
我晕!我的系统内无法输入IP地址高于223的地址,比如输入个224系统就告诉我“224不是一个有效的地址,请输入一个介于1和223之间的数值”
该怎么办呢?
还有NetGhost为什么能在任意网段使用多播发送数据?在100M的网络上用它同时发送100多台计算机20多GB的文件,每台速度都有7~9M每秒,它是怎么做的呢?难道不是多播?Top
3 楼xpdavis(咕嘟-不想孤独)回复于 2004-12-04 19:41:16 得分 0
阁下果然是“初学者”哦,多播地址并不是说在系统配置一个指定的地址,而是将系统加入一个多播组,不需要系统修改本地IP地址来实现多播。系统可以同时加入多个多播组,这是通过socket程序来实现的。在应用程序中加入多播组的进程之间可以互相通信,这些进程可以分布在各个网络,但是跨越网络的多播需要路由支持,也就是说路由器要对多播数据包进行转发,所以经常发生多播数据无法跨网收发的现象,主要是没有得到路由器的支持。如果楼主还不明白的话,建议查阅相关资料,基础知识还是要自己慢慢积累。通过交流的方式主要是解决一些容易碰到的问题,如果太多的概念混淆的话,沟通起来很有难度。Top
4 楼tccsdn(紫乐)回复于 2004-12-07 19:12:43 得分 0
给你个组播的类
#include <vcl.h>
#pragma hdrstop
#include "CMulticastAdmin.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//------------------------------------------------------------------------------
TTcUdp::TTcUdp()
{
mSckReceiver = INVALID_SOCKET;
mMulticaster = INVALID_SOCKET;
// Multicast IP: from 224.0.0.0 to 239.255.255.255
mMulticastIP = 0xef080808; // 239.8.8.8
mMulticastPort = 10018;
mIsReceiving = false;
mRcvThread = NULL;
}
//------------------------------------------------------------------------------
TTcUdp::~TTcUdp()
{
DeleteMulticaster();
DeleteReceiver();
StopReceiving();
}
//------------------------------------------------------------------------------
void TTcUdp::SetMemo( TMemo *Memo )
{
mMemo=Memo;
}
//------------------------------------------------------------------------------
void TTcUdp::SetMulticastIP(DWORD inIP)
{
mMulticastIP = inIP;
}
//------------------------------------------------------------------------------
DWORD TTcUdp::GetMulticastIP(void)
{
return mMulticastIP;
}
//------------------------------------------------------------------------------
void TTcUdp::SetMulticastIP(const char * inIP)
{
mMulticastIP = ntohl(inet_addr(inIP));
}
//------------------------------------------------------------------------------
void TTcUdp::GetMulticastIP(char * outIP)
{
if (outIP)
{
struct in_addr in;
in.S_un.S_addr = htonl(mMulticastIP);
char * pStr = inet_ntoa(in);
strcpy(outIP, pStr);
}
}
//------------------------------------------------------------------------------
void TTcUdp::SetMulticastPort(WORD inPort)
{
mMulticastPort = inPort;
}
//------------------------------------------------------------------------------
WORD TTcUdp::GetMulticastPort(void)
{
return mMulticastPort;
}
//------------------------------------------------------------------------------
bool TTcUdp::CreateMulticaster(void)
{
DeleteMulticaster();
WSADATA data;
int ret = WSAStartup(0x0202, &data);
if (ret != 0)
{
WSACleanup();
return FALSE;
}
mMulticaster = socket(AF_INET, SOCK_DGRAM, 0);
if (mMulticaster == INVALID_SOCKET)
{
WSACleanup();
return false;
}
bool flag = true;
ret = setsockopt( mMulticaster, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag) );
SOCKADDR_IN addr;
ZeroMemory(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(mMulticastPort);
ret = bind( mMulticaster, (struct sockaddr*)&addr, sizeof(addr) );
return true;
}
//------------------------------------------------------------------------------
void TTcUdp::DeleteMulticaster(void)
{
if (mMulticaster != INVALID_SOCKET)
{
closesocket(mMulticaster);
mMulticaster = INVALID_SOCKET;
WSACleanup();
}
}
//------------------------------------------------------------------------------
bool TTcUdp::CreateReceiver(void)
{
DeleteReceiver();
WSADATA data;
int ret = WSAStartup(0x0202, &data);
if (ret != 0)
{
WSACleanup();
return FALSE;
}
mSckReceiver = socket( AF_INET, SOCK_DGRAM, 0 );
if( mSckReceiver == INVALID_SOCKET )
{
WSACleanup();
return false;
}
bool flag = TRUE;
ret = setsockopt( mSckReceiver, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag) );
SOCKADDR_IN addr;
ZeroMemory(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(mMulticastPort);
ret = bind(mSckReceiver, (struct sockaddr*) &addr, sizeof(addr));
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = htonl(mMulticastIP);
mreq.imr_interface.s_addr = INADDR_ANY;
ret = setsockopt( mSckReceiver, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq) );
return true;
}
//------------------------------------------------------------------------------
void TTcUdp::DeleteReceiver(void)
{
if (mSckReceiver != INVALID_SOCKET)
{
closesocket(mSckReceiver);
mSckReceiver = INVALID_SOCKET;
WSACleanup();
}
}
//------------------------------------------------------------------------------
bool TTcUdp::Multicast( const char * inBuffer, long inLength )
{
SOCKADDR_IN addr;
memset((char *) &addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(mMulticastIP);
addr.sin_port = htons(mMulticastPort);
int val = sendto( mMulticaster, inBuffer, inLength, 0, (sockaddr *) &addr, sizeof(addr) );
return (val != SOCKET_ERROR);
}
//------------------------------------------------------------------------------
bool TTcUdp::StartReceiving(void)
{
if (mSckReceiver == INVALID_SOCKET)
{
CreateReceiver();
}
if (mSckReceiver != INVALID_SOCKET)
{
if (mIsReceiving)
{
return true;
}
DWORD threadID = 0;
mRcvThread = CreateThread( NULL, 0, ReceivingThrd, this, 0, &threadID );
return ( mRcvThread != NULL );
}
return false;
}
//------------------------------------------------------------------------------
void TTcUdp::StopReceiving(void)
{
if (mIsReceiving)
{
DeleteReceiver();
if( mRcvThread != NULL )
{
WaitForSingleObject(mRcvThread, INFINITE);
mRcvThread = NULL;
}
}
}
//------------------------------------------------------------------------------
DWORD WINAPI TTcUdp::ReceivingThrd(void * pParam)
{
TTcUdp * pController = (TTcUdp*) pParam;
pController->ReceivingLoop();
return 0;
}
//------------------------------------------------------------------------------
void TTcUdp::ReceivingLoop(void)
{
struct sockaddr_in addr_cli;
int addr_cli_len = sizeof(addr_cli);
char buffer[1024];
long bytes = 0;
mIsReceiving = true;
while (mIsReceiving)
{
int addr_cli_len = sizeof(addr_cli);
bytes = recvfrom( mSckReceiver, (char *)buffer, 1024, 0, (LPSOCKADDR)&addr_cli, (int *) &addr_cli_len);
if (bytes == SOCKET_ERROR || bytes == 0)
{
mIsReceiving = false;
}
else
{
buffer[bytes] = '\0';
char * pStr = inet_ntoa(addr_cli.sin_addr);
mMemo->Lines->Add("接收数据来自:"+AnsiString(pStr) );
mMemo->Lines->Add( AnsiString(buffer));
}
}
}
//------------------------------------------------------------------------------Top
5 楼tccsdn(紫乐)回复于 2004-12-07 19:14:20 得分 0
//---------------------------------------------------------------------------
#ifndef CMulticastAdminH
#define CMulticastAdminH
#include <winsock2.h>
#include <assert.h>
#include <Ws2tcpip.h>
//---------------------------------------------------------------------------
class TTcUdp
{
private:
SOCKET mSckReceiver;
SOCKET mMulticaster;
DWORD mMulticastIP;
WORD mMulticastPort;
bool mIsReceiving;
HANDLE mRcvThread;
TMemo *mMemo;
public:
TTcUdp();
~TTcUdp();
void SetMemo( TMemo *Memo );
void SetMulticastIP(DWORD inIP);
DWORD GetMulticastIP(void);
void SetMulticastIP(const char * inIP);
void GetMulticastIP(char * outIP);
void SetMulticastPort(WORD inPort);
WORD GetMulticastPort(void);
bool CreateMulticaster(void);
void DeleteMulticaster(void);
bool CreateReceiver(void);
void DeleteReceiver(void);
// Sending and Receiving...
bool Multicast(const char * inBuffer, long inLength);
bool StartReceiving(void);
void StopReceiving(void);
private:
void ReceivingLoop( void );
static DWORD WINAPI ReceivingThrd( void * pParam );
};
#endifTop




