通过多播实现局域网上线用户列表 c++实现

        多人在局域网上线,实现用户列表的步骤。

1、程序启动(初始化),单独只有自己。

2、发送广播,给其它用户。

3、接收其它用户发送的信息。

4、更新自己的用户列表

为了简化程序,用控制台实现,用户列表用字符串形式显示。

类 MultiSock 实现,主程序调用

头文件MultiSock.h

#include <list>
using namespace std;
#pragma comment(lib,"WS2_32")
struct hostinfo
{
string hostip;
string hostname;
};
class MultiSock
{
public:
MultiSock(void);
~MultiSock(void);
DWORD m_dwMultiAddr;
USHORT m_port;
SOCKET s;
sockaddr_in si;
hostinfo  m_host; 
list<string>  m_listhost; //上线主机名列表
list<string>  m_listip;   //上线主机IP列表
void RecvPacket(void);//接收广播和发送自己信息到广播组
void DisplayHost(void);//显示主机名列表
};

类实现MultiSock.cpp

#include "stdafx.h"
#include "MultiSock.h"
#include <string>
using namespace  std;


MultiSock::MultiSock(void)
{
WSADATA wsaData;
char hostname[255];
PHOSTENT hostinfo;
WORD sockVersion = MAKEWORD(2,2);

if (WSAStartup(sockVersion,&wsaData) != 0)  

  //载入动态库
{
return;
}

//获取自己本机的电脑名和IP
if (gethostname(hostname,sizeof(hostname)) == 0)
{
         if ((hostinfo = gethostbyname(hostname)) !=NULL)
         {
LPSTR ip = inet_ntoa(*(struct in_addr *)*hostinfo->h_addr_list);
m_host.hostip=ip;
m_host.hostname=hostname;
   m_listhost.push_back(m_host.hostname);
m_listip.push_back(ip);


         }
}
s=socket(AF_INET,SOCK_DGRAM,0);


BOOL bReuse=TRUE;
setsockopt(s,SOL_SOCKET, SO_REUSEADDR,(char*)&bReuse,sizeof(BOOL));
m_dwMultiAddr=inet_addr(m_host.hostip.c_str());
m_port=4567;
//    m_dwMultiAddr=inet_addr("230.1.1.99");
si.sin_family = AF_INET;
si.sin_port = ntohs(m_port);
si.sin_addr.S_un.S_addr = INADDR_ANY;

// INADDR_ANY 监听所有IP
bind(s,(sockaddr*)&si, sizeof(si));


bool bopt=TRUE;
setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char*)&bopt, sizeof(bopt));
int nTTL=64;
int nRet=setsockopt(s,IPPROTO_IP,IP_MULTICAST_TTL,(char*)&nTTL,sizeof(nTTL));
if (nRet==SOCKET_ERROR)
{
return;
}
ip_mreq mcast;
mcast.imr_interface.S_un.S_addr=INADDR_ANY;
mcast.imr_multiaddr.S_un.S_addr=m_dwMultiAddr;
setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mcast,sizeof(mcast));


sockaddr_in sRemote;
sRemote.sin_family=AF_INET;
sRemote.sin_port=htons(m_port);

  //广播给所有地址
sRemote.sin_addr.S_un.S_addr=INADDR_BROADCAST;

int ret=sendto(s,m_host.hostname.c_str(),strlen(m_host.hostname.c_str()),0,(sockaddr*)&sRemote,sizeof(sRemote));
DisplayHost(); //发送后显示自己在线





}




MultiSock::~MultiSock(void)
{
sockaddr_in sRemote;
sRemote.sin_family=AF_INET;
sRemote.sin_port=htons(m_port);
sRemote.sin_addr.S_un.S_addr=INADDR_BROADCAST;
int ret=sendto(s,"Leave this party\r\n",strlen("Leave this party\r\n"),0,(sockaddr*)&sRemote,sizeof(sRemote));


ip_mreq mcast;
mcast.imr_interface.S_un.S_addr=INADDR_ANY;
mcast.imr_multiaddr.S_un.S_addr=m_dwMultiAddr;
setsockopt(s,IPPROTO_IP,IP_DROP_MEMBERSHIP,(char*)&mcast,sizeof(mcast));


int nRecvBuf=32*1024;
setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
int nSendBuf=32*1024;
setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));




WSACleanup();
}


void MultiSock::RecvPacket(void)
{
MessageBox(NULL,TEXT("程序开始接收"),TEXT("接收"),MB_OK);
char buf[10280];
char err[10];
int nAddrLen = sizeof(si);
PHOSTENT  hostinfo;
while(TRUE)
{
Sleep(50);
int nRet = ::recvfrom(s,buf,sizeof(buf),0,(sockaddr*)&si,&nAddrLen);
bool bflag=false;
if (nRet != SOCKET_ERROR)
{
buf[nRet]='\0';
if ((strcmp(buf,m_host.hostname.c_str())))
{
    //列表中主机名不在加入列表,避免重复上线

                             for (list<string>::iterator l_host=m_listhost.begin();l_host!=m_listhost.end();++l_host)
{
bflag=false;
if (strcmp(buf,l_host->c_str()))
{
bflag=true;
}
}
if (bflag)
{
m_listhost.push_back(buf);


if (gethostname(buf,sizeof(buf)) == 0)
{
if ((hostinfo = gethostbyname(buf)) !=NULL)
{
 LPSTR ip = inet_ntoa(*(struct in_addr *)*hostinfo->h_addr_list);
 m_listip.push_back(ip);
     m_dwMultiAddr=inet_addr(ip);
     sockaddr_in sRemote;
     sRemote.sin_family=AF_INET;
     sRemote.sin_port=htons(m_port);
     sRemote.sin_addr.S_un.S_addr=INADDR_BROADCAST;

                                             //发送自己的主机名给其它人员
    int ret=sendto(s,m_host.hostname.c_str(),strlen(m_host.hostname.c_str()),0,(sockaddr*)&sRemote,sizeof(sRemote));
}
}
DisplayHost(); //有新加入的成员重新刷新列表
}

}




// MessageBox(NULL,buf,TEXT("數據"),MB_OK);

}
else
{
int n=::WSAGetLastError();
itoa(n,err,10);
MessageBox(NULL,err,TEXT("數據"),MB_OK);
break;
}
}


}

//显示列表
void MultiSock::DisplayHost(void)
{
string display;
for (list<string>::iterator l_host=m_listhost.begin();l_host!=m_listhost.end();++l_host)
{
display.append(*l_host);
}
MessageBox(NULL,display.c_str(),TEXT("在線"),MB_OK);
}

主程序main.cpp

#include "stdafx.h"
#include "MultiSock.h"


int _tmain(int argc, _TCHAR* argv[])
{
MultiSock mySock;
mySock.RecvPacket();
getchar();
return 0;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
局域网盘服务器端是一种可以在服务器上安装的应用程序,它可以让多个用户在同一网络环境下共享文件,提高工作效率和协作能力。以下是局域网盘服务器端的实现步骤: 1. 确定服务器端功能 在实现局域网盘服务器端之前,需要确定服务器端需要实现的功能。常见的局域网盘服务器端功能包括文件上传和下载、文件共享和协作、用户权限管理、文件版本控制、文件搜索和分类、文件加密和安全、数据备份和恢复等。 2. 选择服务器端开发平台和语言 根据服务器端功能的需求,选择合适的开发平台和语言,如Java、Python、PHP、C++等。选择合适的开发平台和语言可以加快开发进度,提高服务器端性能和稳定性。 3. 实现服务器端业务逻辑 设计和实现服务器端业务逻辑,包括用户身份验证和授权、文件上传和下载处理、文件共享和协作处理、用户权限管理处理、文件版本控制处理、文件搜索和分类处理、文件加密和安全处理、数据备份和恢复处理等。 4. 实现服务器端存储逻辑 设计和实现服务器端存储逻辑,包括文件存储管理、文件元数据管理、文件索引管理、文件版本管理等。服务器端需要选择合适的存储方案,如本地硬盘、网络存储设备等。 5. 实现服务器端API接口 设计和实现服务器端API接口,允许客户端应用程序通过API接口来访问服务器端的功能。API接口包括文件上传和下载接口、文件共享和协作接口、用户权限管理接口、文件版本控制接口、文件搜索和分类接口、文件加密和安全接口、数据备份和恢复接口等。 6. 测试和调试服务器端应用程序 在完成服务器端应用程序的开发之后,进行测试和调试,保证服务器端应用程序的稳定性和可靠性。测试和调试包括功能测试、性能测试、兼容性测试、安全测试等。 7. 发布和维护服务器端应用程序 在完成测试和调试之后,发布服务器端应用程序,并进行后续的维护和更新,保证服务器端应用程序的正常使用和功能完善。 总之,实现局域网盘服务器端需要根据服务器端功能需求选择合适的开发平台和语言,设计和实现业务逻辑和存储逻辑,设计和实现API接口,进行测试和调试,发布和维护服务器端应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值