搜档网
当前位置:搜档网 › SOCKET之UDP跨网段广播返回服务端主机名和所有IP

SOCKET之UDP跨网段广播返回服务端主机名和所有IP

// myudpclient.cpp : 定义控制台应用程序的入口点。
//
#pragma once
#include "stdafx.h"
#include "targetver.h"
#include
#include
#include
#include
#include
#include
//#include
//#include
//#include
//#include
//#include
#pragma comment ( lib, "ws2_32.lib" )
#include
using namespace std;
#define MAXLINE 1024
#define SERV_PORT 4000

void ShowMessage(char *buff){//处理接受到的报文
char arrayINFO[10][MAXLINE]={0};
//存放数据的数组,第一个为返回的客户端名称,若与本机名称相同,则接收。第二个为服务端名称,其后为其IP
int j=0,k=0;
int i;
for(i = 0;buff[i];i++){
if(buff[i]=='?'){
strncpy(arrayINFO[j],&buff[k],i-k);
k=i+1;
j++;
}
}
strncpy(arrayINFO[j],&buff[k],i);
char localHostName[MAXLINE]={0};
gethostname(localHostName,MAXLINE);
if(strcmp(localHostName,arrayINFO[0])==0){
cout<for(int temi=1;temicout<<" 第"<}
}
}


int main(){

WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2),&wsaData)!=NO_ERROR)
{
std::cout<<"Initialization failed"<}else{
cout<<"initialization success"<}
//创建UDP的套接字
SOCKET socket1=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(INVALID_SOCKET == socket1)
{
cout<<"socket error"<}else{
cout<<"socket success"<}

// 用来发送和接收数据
struct sockaddr_in client;
client.sin_family = AF_INET;
client.sin_port = htons(4000);
client.sin_addr.s_addr = INADDR_BROADCAST;
//client.sin_addr.S_un.S_addr = inet_addr("255.255.255.255");//和上面一条语句一个意思,不过要对应好子网掩码
//设置该套接字为广播类型,
bool bOpt = true;
setsockopt(socket1,SOL_SOCKET,SO_BROADCAST,(char*)&bOpt,sizeof(bOpt));

int nAddrLen = sizeof(SOCKADDR);
char buff[MAXLINE] = "";

int nLoop = 0;
int err;


while(1)
{
//广播一条消息
char localHostName[MAXLINE]={0};
gethostname(localHostName,MAXLINE);
char SendMes[MAXLINE]={0};
cout<cin.getline(SendMes,MAXLINE,'\n');
strcat(localHostName,"?");
strcat(localHostName,SendMes);//将本主机信息和发送的信息绑定到一个数组

//cout<<"IP发送前"<int nSendSize = sendto(socket1,localHostName,strlen(localHostName),0,(SOCKADDR*)&client,sizeof(SOCKADDR));
if(SOCKET_ERROR == nSendSize){
err = WSAGetLastError();
cout<<"send 主机名 error!, error code is"<}else{
cout<<"发送成功"<}
//cout<<"IP发送后"<

_ntoa(client.sin_addr)<//等待客户端返回其主机名和IP

//设置超时信息
int nTimeOut = 1500 ;
setsockopt(socket1,SOL_SOCKET,SO_RCVTIMEO,(char *)&nTimeOut,sizeof(int));

while(1){
char buff[1024]={0};
recvfrom(socket1,buff,MAXLINE,0,(SOCKADDR*)&client,&nAddrLen);
client.sin_addr.s_addr = INADDR_BROADCAST;
if(strlen(buff)<=0){
//printf("接收超时!");
break;
}else{
ShowMessage(buff);
}

}
client.sin_addr.s_addr = INADDR_BROADCAST;//须重新初始化广播地址,不然其会记录为上一次发送的地址,就不再sendto广播了
}//while1结束

}









// myudpserver.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#pragma comment ( lib, "ws2_32.lib" )
#include
using namespace std;
#define MAXLINE 1024
#define SERV_PORT 4000


void GetInfo(char* SendInfo){//取得本地计算机名和IP

char localHostName[MAXLINE]={0};
gethostname(localHostName,MAXLINE);
//根据计算机名取得所有IP
strcat(SendInfo,localHostName);
hostent* pHostent = gethostbyname(localHostName);
hostent& he=*pHostent;
sockaddr_in sa;
for (int nAdapter=0; he.h_addr_list[nAdapter]; nAdapter++) {
memcpy ( &sa.sin_addr.s_addr, he.h_addr_list[nAdapter],he.h_length);
LPCSTR ip=inet_ntoa(sa.sin_addr);
string strIP;
strIP=ip;
char localIP[MAXLINE]={0};
strcpy(localIP,strIP.c_str());//将string字符串转化成数组,用localIP存储。
strcat(SendInfo,"?");
strcat(SendInfo,localIP);
}
}
void ShowMessage(char *buff,char *ClientHName){//处理接受到的报文
char arrayINFO[2][MAXLINE]={0};//存放数据的数组,第一个为主机名,第二个消息
int j=0,k=0;
int i;
for(i = 0;buff[i];i++){
if(buff[i]=='?'){
strncpy(arrayINFO[0],buff,i);
break;
}
}
strncpy(arrayINFO[1],&buff[i+1],strlen(buff));
cout<<"接受到"<strcat(ClientHName,arrayINFO[0]);
}
int main()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2),&wsaData)!=NO_ERROR)
{
std::cout<<"Initialization failed"<}else{
cout<<"initialization success"<}

//创建socket
SOCKET socket1=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);

if(socket1==INVALID_SOCKET){
cout<<"socket fail"<}else {
cout<<"socket success"<//设置该套接字为广播类型
bool bOpt = true;
// 用来绑定套接字
struct sockaddr_in server;
server.sin_family=AF_INET;
server.sin_port=htons(4000); ///监听端口
//server.sin_addr.s_addr = 0;
server.sin_addr.s_addr = htonl(INADDR_ANY);

setsockopt(socket1,SOL_SOCKET,SO_BROADCAST,(char*)&bOpt,sizeof(bOpt));
//绑定套接字
if(bind(socket1,(struct sockaddr*)&server,sizeof(SOCKADDR))==-1)
{
cout<<"bind fail"<}else {
cout<<"bind

success"<}
}

//取得本机信息
char SendInfo[MAXLINE]={0};
GetInfo(SendInfo);

// 用来发送和接收数据
struct sockaddr_in client;
client.sin_family = AF_INET;
client.sin_port = htons(4000);
client.sin_addr.s_addr = INADDR_BROADCAST; //////////////////////////
int err; int nAddrLen = sizeof(SOCKADDR);

while(1)
{
char buff[MAXLINE]={0};
char ClientHName[MAXLINE]={0};//客户端主机名
cout<<"正在监听..."<//接收客户端传来的消息

if(recvfrom(socket1,buff,MAXLINE,0,(SOCKADDR*)&client,&nAddrLen)!=SOCKET_ERROR){
ShowMessage(buff,ClientHName);
client.sin_addr.s_addr = INADDR_BROADCAST;
//没有这句话的话,sendto不能跨到其他网段。意思是必须得广播才能跨网段
//strcat(SendInfo,ClientHName);//将客户端主机名并入SendInfo数组
strcat(ClientHName,"?");
strcat(ClientHName,SendInfo);//将客户端主机名并入ClientHName数组,然后发送ClientHName
if(sendto(socket1,ClientHName,strlen(ClientHName),0,(SOCKADDR*)&client,nAddrLen) == SOCKET_ERROR)
{
err = WSAGetLastError();
cout<<"send error!, error code is"<}else{
cout<<"返回本机信息成功"<}
client.sin_addr.s_addr = INADDR_BROADCAST;
}

}

}













相关主题