通過廣播獲取ip位址的實現

2021-09-28 18:34:08 字數 4243 閱讀 4526

但這個過程有幾個問題要考慮。第一點,如果接收方有多個網絡卡,我怎麼知道「hello」包是通過哪個網絡卡接收的呢?第二點,在接收方我可以用監聽那個廣播埠的socket來傳送訊息嘛?

對於第一點,也是苦惱了我很久的問題,最終找到了方法:getsockname,這個函式可以根據addr來得到ip位址,用c語言學習網路程式設計的都知道接收函式是有乙個sockaddr_in結構體來接收傳送方的ip和埠資訊的,而這個函式就是根據這個結構體來解析的,但是這個函式有乙個條件是一定要在連線的情況下才能獲取本地ip位址,不過也對,連線了,網絡卡一定也就確定了。既然要連線那反正udp套接字也可以connect,我們多寫一點就是了。

對於第二點,答案是不可以,因為我也嘗試了這樣的做法,在傳送方接收到的ip訊息會出現亂碼的情況。所以在傳送方和接收方都要多建立乙個用於傳送該訊息的socket。總體來說就是,傳送方和接收方都要有乙個socket用來廣播"hello"包和接收"hello"包,並且還都要有乙個udp socket來傳送udp訊息和接收udp訊息。

話不多說,上**

//傳送方--廣播「hello」包然後接收接收方傳送的ip訊息

#include #include #include #include #pragma comment (lib,"ws2_32.lib")

#define buf_size 100

void error_handling(const char* message);

int main(int argc,char* ar**)

socket send_sock,recv_sock;

sockaddr_in broad_adr;

char send_msg[buf_size]="hello,world",rec_msg[buf_size];;

int so_brd = 1;

//建立send_sock並與廣播位址進行關聯

send_sock = socket(pf_inet,sock_dgram,0);

if (send_sock == invalid_socket)

error_handling("send_sock error!");

memset(&broad_adr,0,sizeof(broad_adr));

broad_adr.sin_family = af_inet;

broad_adr.sin_addr.s_addr = htonl(inaddr_broadcast);

broad_adr.sin_port = htons(atoi(ar**[1]));

//設定廣播選項

int getinfo = setsockopt(send_sock,sol_socket,so_broadcast,(const char*)&so_brd,sizeof(so_brd));

if (getinfo == socket_error)

error_handling("setsockopt error!");

printf("setsockopt has done\n");

//建立recv_sock並與本地位址進行繫結

recv_sock = socket(pf_inet, sock_dgram, 0);

if (recv_sock == invalid_socket)

error_handling("recv_sock error!");

struct sockaddr_in myadr, youradr;

memset(&myadr, 0, sizeof(myadr));

myadr.sin_family = af_inet;

myadr.sin_addr.s_addr = htonl(inaddr_any);

myadr.sin_port = htons(10244);

if (bind(recv_sock, (struct sockaddr*)&myadr, sizeof(myadr)) == socket_error)

error_handling("bind error!");

else printf("bind has done\n");

//傳送helloworld訊息

int send_len;

send_len = sendto(send_sock,send_msg,strlen(send_msg),0,(sockaddr*)&broad_adr,sizeof(broad_adr));

if(send_len == -1)

error_handling("sendto error!");

else printf("sendto has done\n");

closesocket(send_sock); //傳送完後關閉傳送的socket

//接收來自receive.cpp執行端的ip訊息並輸出ip

int yadr_sz = sizeof(youradr);

int recv_len = recvfrom(recv_sock, rec_msg, buf_size, 0, (sockaddr*)&youradr, &yadr_sz);

if (recv_len == -1)

error_handling("recvfrom error!");

else

closesocket(recv_sock);

wsacleanup();

return 0;

} void error_handling(const char* message)

//傳送方接收到「hello」包後獲取本機ip位址然後封裝到udp資料報裡傳送

#include #include #include #include #include #pragma comment (lib,"ws2_32.lib")

#define buf_size 100

void error_handling(const char* message);

int main(int argc, char* ar**)

char rec_msg[buf_size],send_msg[buf_size] = "the receiver ip is ";

socket send_sock,recv_sock;

send_sock = socket(pf_inet, sock_dgram, 0);

if (send_sock == invalid_socket)

error_handling("send_sock error!");

recv_sock = socket(pf_inet, sock_dgram, 0);

if(recv_sock == invalid_socket)

error_handling("recv_sock error!");

sockaddr_in adr,youradr;

//set adr

memset(&adr, 0, sizeof(adr));

adr.sin_family = af_inet;

adr.sin_addr.s_addr = htonl(inaddr_any);

adr.sin_port = htons(atoi(ar**[1]));

//bind socket and adr

if (bind(recv_sock,(sockaddr*)&adr,sizeof(adr)) == -1)

error_handling("bind error!");

else printf("bind has done\n");

//receive message

int your_adr_sz = sizeof(youradr);

int strlen = recvfrom(recv_sock, rec_msg, buf_size, 0, (sockaddr*)&youradr, &your_adr_sz);

if (strlen == -1)

error_handling("recvfrom error!");

else

closesocket(send_sock);

closesocket(recv_sock);

wsacleanup();

return 0;

}void error_handling(const char* message)

以下是在虛擬機器上除錯的結果:

通過UDP廣播自動獲取IP位址

客戶端 socket ssrv sockaddr in addrto wsadata wsdata bool bsocket 啟動socket庫,版本為2.0 word wver makeword 2,0 if 0 wsastartup wver,wsdata bsocket true 然後賦值給位...

通過IP獲取MAC位址

option explicit private declare function openprocess lib kernel32 byval dwdesiredaccess as long,byval binherithandle as long,byval dwprocessid as long...

IP廣播位址

ip廣播位址有四種型別 網路的網路掩碼,甚至連它的ip位址也不知道。例如當主機從dhcp或bootp伺服器獲取ip位址時。傳送給ip位址255.255.255.255的資料報 屬於有限廣播資料報。在指定給本地網路的廣播資料報時,目的位址的網路標識部分和主機標識部分全都是1 255.255.255.2...