但這個過程有幾個問題要考慮。第一點,如果接收方有多個網絡卡,我怎麼知道「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...