why utp_write can only be called once in the callback function, if calling utp_write again to send data has no effect.
// Callback for when data is received
uint64 on_read(utp_callback_arguments *a) {
printf("Client received %zu bytes: %.*s\n", a->len, (int) a->len, a->buf);
fflush(stdout);
return 0;
}
// Callback for when a connection is established
uint64 on_connect(utp_callback_arguments *a) {
printf("Client: Connected\n");
const char *message = "Hello from client!";
utp_write(a->socket, (const byte *) message, strlen(message));
fflush(stdout);
return 0;
}
// Callback for sending data
uint64 on_sendto(utp_callback_arguments *a) {
int sock = (int) (intptr_t) utp_get_userdata(a->context);
ssize_t sent = sendto(sock, a->buf, a->len, 0, a->address, a->address_len);
return (sent < 0) ? 1 : 0; // Return non-zero on error
}
...
int sock = socket(AF_INET, SOCK_DGRAM, 0);
...
utp_context *ctx = utp_init(2);
...
utp_set_userdata(ctx, (void *) (intptr_t) sock);
utp_set_callback(ctx, UTP_ON_READ, (void *) on_read);
utp_set_callback(ctx, UTP_ON_CONNECT, (void *) on_connect);
utp_set_callback(ctx, UTP_ON_ERROR, (void *) on_error);
utp_set_callback(ctx, UTP_ON_STATE_CHANGE, (void *) on_state_change);
utp_set_callback(ctx, UTP_SENDTO, (void *) on_sendto);
utp_socket *s = utp_create_socket(ctx);
utp_connect(s, (const struct sockaddr *) &addr, sizeof(addr));
byte buffer[65536];
while (1) {
struct sockaddr_in src_addr;
socklen_t addrlen = sizeof(src_addr);
ssize_t len = recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr *) &src_addr, &addrlen);
if (len < 0) {
perror("recvfrom");
break;
}
utp_process_udp(ctx, buffer, len, (struct sockaddr *) &src_addr, addrlen);
utp_check_timeouts(ctx);
}
utp_destroy(ctx);
...
why utp_write can only be called once in the callback function, if calling utp_write again to send data has no effect.