由于测试需要,自己用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;
}