我遇到了一个非常奇怪的错误。我有一个 struct sender
,它封装了 UDP sendto() 所需的资源。发送方有一个send()
方法,它封装了BSD套接字sendto()
。
以下代码有效。
alice = sender(bob_ip, bob_port);
alice.send();
BUG以下代码失败
alice = sender(bob_ip, bob_port);
puts("====");
alice.send();
如果我将 I/O 或 sleep 操作(例如此处的 put("===="))放入 alice.send()
方法。它仍然有效。
谁能解释一下为什么会发生这种情况? 完整源代码:
// To run this code: ./sender <remote-ip> <remote-port>
#define IP4_STR_LEN 20
unsigned bob_port;
char bob_ip[IP4_STR_LEN];
int msg_len;
char msg[50];
const size_t SOCKADDR_IN_LEN = sizeof(struct sockaddr_in);
typedef struct sender {
int sockfd_s;
struct sockaddr* rem_addr;
} sender;
static void init(sender* this, char* rem_ip, int rem_port) {
this->sockfd_s = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in local_in, rem_in;
memset(&rem_in, 0, sizeof(rem_in));
rem_in.sin_family = AF_INET;
rem_in.sin_port = htons(rem_port);
inet_pton(AF_INET, rem_ip, &(rem_in.sin_addr));
this->rem_addr = (struct sockaddr*)&rem_in;
}
static int sendudp(sender* this){
int msg_snt_len = sendto(this->sockfd_s, msg, msg_len, 0, this->rem_addr, SOCKADDR_IN_LEN);
printf("msg_snt_len: %d\n", msg_snt_len);
return msg_snt_len;
}
sender alice;
static void test() {
init(&alice, bob_ip, bob_port);
puts("====");
sendudp(&alice);
}
int main(int argc, char* argv[]) {
strcpy(bob_ip, argv[1]);
sscanf(argv[2], "%u", &bob_port);
strcpy(msg, "Hello World!");
msg_len = strlen(msg);
test();
return 0;
}
最佳答案
您正在初始化该结构以指向仅作为 init()
函数内的局部变量存在的变量。
一旦该函数退出,这些指针就无效并取消引用它们(就像 sendto()
一样,因为您将该指针传递给了它)。会给你未定义的行为。
您应该将实际地址数据添加到结构本身,以便它保留下来。
关于c - 调用 I/O 或 sleep() 后 UDP sendto() 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26522730/