给定一个套接字文件描述符,是否可以检查 UDP 套接字是否已连接?
int sock_fd = -1;
void create_socket() {
if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("udp socket() failed");
exit(EXIT_FAILURE);
}
}
sockaddr_in create_sock_addr(const char* ip, const uint16_t port) {
sockaddr_in sock_addr{};
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons(port);
if (inet_aton(ip, &sock_addr.sin_addr) == 0) {
perror("udp inet_aton() failed");
exit(EXIT_FAILURE);
}
return sock_addr;
}
void connect_socket(const char* ip, const uint16_t port) {
const sockaddr_in sock_addr = create_sock_addr(ip, port);
if (connect(sock_fd, (const sockaddr*)&sock_addr, sizeof(sockaddr_in)) == -1) {
perror("udp connect() failed");
exit(EXIT_FAILURE);
}
}
bool is_sock_connected() {
// check sock_fd is connected or not
return true;
}
int main() {
create_socket();
connect_socket("127.0.0.1", 12345);
if (is_sock_connected()) {
// use send() function to send data
} else {
// use sendto() function to send data
}
close(sock_fd);
}
管理与服务器或客户端的连接的更好方法是使用
select()
或 poll()
/epoll()
等函数
void
handle_sock_msg(int sock_fd)
{
int err;
fd_set read;
fd_set write;
FD_ZERO(&read);
FD_ZERO(&write);
FD_SET(sock_fd, &read);
FD_SET(sock_fd, &write);
err = select(sock_fd + 1, &read, &write, NULL, NULL);
if (err <= 0)
return ;
if (FD_ISSET(sock_fd, &read))
{
// msg to read/recv
}
if (FD_ISSET(sock_fd, &write))
{
// server handle write/send
}
return ;
}
这可以让您在调用
send()
或 recv()
之前知道套接字中附加了什么。
当您使用
connect()
服务器接收一条特殊的“消息”时,会收到通知您正在尝试连接到他。
处理该连接是他的工作,如果您只创建一个客户端,您不应该关心它。
当服务器关闭与客户端的连接时,他会发送一个
EOF
字符。