• 全部
  • 问答

有关多播通讯的深入讨论--交换机对多播的支持?

romijn 2004-03-22 01:34:08
本人做了一视频服务器的程序,传送视频图像采用,udp在局域网内发送组播,客户端程序启动的时候加入多播组,同时开始组内数据的接收。通过windows2000的网络监视器来查看客户端Windows2k的网络接收情况,发现没有开启视频客户端的时候,网络利用率很小,网络接收到一些数据桢但不是太大;开启了视频客户端后,网络利用率马上提升到了10%左右,数据桢也增加了许多。通过以上的情况可以断定我的多播程序是没有问题的。
本人的程序的问题如下:当视频服务器程序打开的时候,不管客户端有没有开启,交换机(本人的交换机为一般的10M/100M自适应的交换机)上所有的端口的数据交换指示灯不停的在闪烁,这时网络发生了堵塞,各个机器都无法通过网关上网。只要一关服务器程序,交换机马上正常,各台机器就可以上网。
有人说是这种情况是交换机不支持多播,把数据复制到各个端口,所以和广播的效果一样,所以会产生网络风波?是这样的吗?希望高手指点。
...全文
43 点赞 收藏 6
写回复
6 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
romijn 2004-03-22
if(!m_Socket.IsConnected()){
m_Socket.Create("224.0.0.99",2002,this->m_hWnd);
if(!m_Socket.IsConnected()){
AfxMessageBox("Socket初试化失败!");
return;
}

//生成视频数据包装结构v
...
m_Socket.Send((char*)&v,sizeof(v))
回复
romijn 2004-03-22
程序代码
CMultiCast::CMultiCast()
{
m_hWnd = NULL;
m_bConnected = FALSE;
}

CMultiCast::~CMultiCast()
{

}

BOOL CMultiCast::Create(CString lpstrAddr, unsigned short port, HWND hWnd)
{

if(m_bConnected){
TRACE("Has Successfully Create the socket!\n");
return FALSE;
}
m_hWnd = hWnd;

int ret;
int cbRet = 0;
int nIP_TTL =1;//设置IP数据生存期
BOOL bFlag;
WSADATA wsaData;

//WORD version = MAKEWORD(2, 0);
WORD version = MAKEWORD(2, 2);
//初试化socket
ret = WSAStartup(version, &wsaData);
if(ret != 0)
TRACE("Initilize Error!\n");
//生成socket
m_hSocket = WSASocket(AF_INET, SOCK_DGRAM,/* IPPROTO_UDP,NULL,0,0);*/
IPPROTO_UDP, (LPWSAPROTOCOL_INFO)NULL, 0,
WSA_FLAG_OVERLAPPED | WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF);

if (m_hSocket == INVALID_SOCKET){
TRACE("WSASocket:%d\n",WSAGetLastError());
return FALSE;
}

bFlag = TRUE; // 设置套接字为可重用端口地址
ret = setsockopt(m_hSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&bFlag,
sizeof (bFlag));

if(ret == SOCKET_ERROR){
TRACE("setsockopt:%d",WSAGetLastError());
return FALSE;
}
// 将套接字绑扎到用户指定端口及默认的接口
memset(&addr,0,sizeof(addr));
addr.sin_family = AF_INET;//PF_INET;
addr.sin_port = htons (port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind (m_hSocket, (struct sockaddr FAR *)&addr,
sizeof(struct sockaddr));

if (ret == SOCKET_ERROR){
TRACE("bind: %d", WSAGetLastError());
return FALSE;
}
// 设置多址广播数据报传播范围(TTL)
ret = WSAIoctl(m_hSocket, SIO_MULTICAST_SCOPE, &nIP_TTL,
sizeof (nIP_TTL), NULL, 0, (unsigned long*)&cbRet, NULL, NULL);
if (ret == SOCKET_ERROR){
TRACE("SAIoctl(SIO_MULTICAST_SCOPE):%d\n",WSAGetLastError());
return FALSE;
}

//设置多播返回(LOOKBACK)

BOOL nLoopBack=FALSE;//m_JoinDlg.m_Loopback;
ret = WSAIoctl(m_hSocket,SIO_MULTIPOINT_LOOPBACK,&nLoopBack,sizeof(nLoopBack),
NULL,0,(unsigned long*)&cbRet,NULL,NULL);
if (ret == SOCKET_ERROR){
TRACE("WSAIoctl:%d\n",WSAGetLastError());
return FALSE;
}

memset(&srcaddr,0,sizeof(srcaddr));
srcaddr.sin_family=AF_INET;
srcaddr.sin_addr.s_addr=inet_addr(lpstrAddr);
srcaddr.sin_port=htons(port);

//WSABUF wsaCalleeData;
m_hGroupSocket = WSAJoinLeaf(m_hSocket, (PSOCKADDR)&srcaddr,
sizeof(srcaddr), NULL, /*&wsaCalleeData*/NULL, NULL, NULL, JL_BOTH);

if (m_hGroupSocket == INVALID_SOCKET){
m_bConnected = FALSE;
TRACE("WSAJoinLeaf():%d\n", WSAGetLastError());
return FALSE;
}

ret = WSAAsyncSelect(m_hGroupSocket, m_hWnd, WM_MULTIPOINTEVENT,
FD_WRITE | FD_READ | FD_QOS | FD_GROUP_QOS | FD_CONNECT);

if(ret == SOCKET_ERROR){
TRACE("WSAAsyncSelect():%d\n", WSAGetLastError());
m_bConnected = FALSE;
return FALSE;
}
m_bConnected = TRUE;
return TRUE;
}

int CMultiCast::Send(char *lpData, int size)
{
if(m_hSocket == INVALID_SOCKET)
return -1;
unsigned long nDataSent = 0;
int nReturnCode;
WSABUF wsaBuf;
wsaBuf.len = size;
wsaBuf.buf = lpData;
nReturnCode = WSASendTo(/*m_hSocket*/m_hGroupSocket, &wsaBuf, 1, &nDataSent,
0, (LPSOCKADDR)&srcaddr, sizeof(SOCKADDR), NULL, NULL);
if(nReturnCode == SOCKET_ERROR){
TRACE0("Error in send packets to the network!\n");
return -1;
}

return nDataSent;
}

int CMultiCast::Receive(char *lpData, int size)
{
int nReturnCode ;
WSABUF wsaRecvBuf;
wsaRecvBuf.buf = lpData;
wsaRecvBuf.len = size;
unsigned long cbRet = 0;

int iLen = sizeof (srcaddr);
int dFlag = 0;

nReturnCode = WSARecvFrom(m_hGroupSocket, &wsaRecvBuf, 1,
&cbRet, (unsigned long*)&dFlag, (struct sockaddr *)&srcaddr,
&iLen, NULL, NULL);
if(nReturnCode == SOCKET_ERROR){
if(WSAEWOULDBLOCK == WSAGetLastError())
TRACE("Socket will block!\n");
else{
if(WSAGetLastError() == WSA_IO_PENDING)
TRACE("IO is pending!\n");
else
return -1;
}
TRACE("RecvFrom Error:%d\n", WSAGetLastError());
}
//本次操作没有接收到数据
if(cbRet == 0)
return 0;

//通知父窗口读数据
return cbRet;
}

void CMultiCast::Initilize()
{
/*
WSADATA wsaData;
WORD version = MAKEWORD(2, 0);
int ret = WSAStartup(version, &wsaData);
if(ret != 0)
TRACE("Initilize Error!\n");
*/
}

void CMultiCast::Unintilize()
{
//closesocket(m_hGroupSocket);
//closesocket(m_hSocket);
if (WSACleanup() != 0){
TRACE("UnInitilize Error:%d\n", WSAGetLastError());
}
}

BOOL CMultiCast::IsConnected()
{
return m_bConnected;
}

void CMultiCast::Close()
{
closesocket(m_hSocket);
closesocket(m_hGroupSocket);
m_bConnected = FALSE;
}
回复
romijn 2004-03-22
多谢这么多热心人,我觉得程序没有错!下面贴出来给大家看看。我的程序发送的数据量非常的大。
头文件
#include "Winsock2.h"
#pragma comment(lib,"Ws2_32.lib")

#define WM_MULTIPOINTEVENT WM_USER + 1001

class CMultiCast : public CObject
{
public:
void Close();
BOOL IsConnected();
static void Unintilize();
static void Initilize();
int Receive(char* lpData, int size);
int Send(char* lpData, int size);
BOOL Create(CString lpstrAddr, unsigned short port, HWND hWnd);
CMultiCast();
virtual ~CMultiCast();

private:
HWND m_hWnd;
SOCKET m_hSocket;
SOCKET m_hGroupSocket;
BOOL m_bConnected;

SOCKADDR_IN addr;
SOCKADDR_IN srcaddr;
};
回复
awjx 2004-03-22
帮你顶一下
回复
stonesky 2004-03-22
这样会出现网络风暴吗?我认为是程序有问题
回复
romijn 2004-03-22
自己顶一下!
回复
相关推荐
发帖
通信技术
创建于2007-08-27

4037

社区成员

通信技术相关讨论
申请成为版主
帖子事件
创建了帖子
2004-03-22 01:34
社区公告
暂无公告