由於測試需要,自己用vconfig在自己的虛擬機裏添加了很多ip,實現不同Ip間的通信。UDP客戶端向服務器發送報文時,綁定會有最近IP原則,比如,你機器上有如下幾個IP:10.1.1.1 ,10.1.1.2 , 10.1.1.50, 10.1.2.51 , 10.1.2.90 , 10.1.3.91 ,10.0.0.1, 192.168.42.137,現在要向192.168.42.1發送報文,系統會自動給你分配離192.168.42.1最近的ip 192.168.42.137綁定,如果我們要用10.1.1.1這個Ip給任何一個ip發送報文,並接收ack就必須在綁定時綁定10.1.1.1這個ip,源碼如下
int net_bind(int sock_fd, const char *bind_addr) {
struct sockaddr_in host_addr;
memset(&host_addr, 0, sizeof(host_addr));
host_addr.sin_family = AF_INET;
host_addr.sin_port = htons(0);
// host_addr.sin_addr.s_addr = inet_addr(bind_addr);
// host_addr.sin_addr.s_addr = htonl("10.1.1.1");
if (inet_pton(AF_INET, bind_addr, &host_addr.sin_addr) <= 0) {
cout << "Initializing UDP ip err " << endl;
}
if (-1 != bind(sock_fd, (struct sockaddr *) &host_addr, sizeof(host_addr)))
return 0;
prt_err_msg(s_isDebug, "not implement", 0);
return -1;
}
傳入指定IP,並顯式調用該函數,由於UDP通信系統會自動分配端口,所以我們可以將端口設爲0,系統會自動分配
int net_udp_send(int sock_fd, const char *buff, size_t buff_size,
const char *dst_addr, int port) {
int ret_send = 0;
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = inet_addr(dst_addr);
if (-1 != (ret_send = sendto(sock_fd, buff, buff_size, 0,
(struct sockaddr *) (&server_addr), sizeof(server_addr))))
return ret_send;
prt_err_msg(s_isDebug, "sendto error", errno);
return -1;
}
int net_udp_recv(int sock_fd, char *buff, size_t buff_size, char *recv_addr,
size_t *recv_size, int *recv_port) {
int ret_recv = 0;
char *addr;
socklen_t server_addr_size = sizeof(struct sockaddr_in);
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
if (-1 != (ret_recv = recvfrom(sock_fd, buff, buff_size, 0,
(struct sockaddr *) (&server_addr), &server_addr_size))) {
addr = inet_ntoa(server_addr.sin_addr);
memcpy(recv_addr, addr, strlen(addr));
*recv_port = ntohs(server_addr.sin_port);
return ret_recv;
}
prt_err_msg(s_isDebug, "recvfrom error", errno);
return -1;
}