UDP客户端与服务端执行bind和connect

发布于:2024-03-21 ⋅ 阅读:(80) ⋅ 点赞:(0)

udp服务器使用connect()函数指明套接字的目的地址/端口号,使服务器只接受特定主机的请求;
udp服务器调用了bind()函数为服务器套接字绑定本地地址/端口,使得客户端知道发数据的目的地址/端口;

udp客户端调用connect()函数指明目的地址/端口后,可使用send()函数向目的地址发送数据;
udp客户端在发送数据之前, 用bind()函数绑定本地地址/端口, 可避免操作系统该套接字随机分配地址信息和端口号;

上代码

配置参数

#define INET_SERVER_IP_ADDR    "192.168.1.39"
#define INET_CLIENT_IP_ADDR    "192.168.1.102"


#define SERVER_UDP_PORT    "9877"
#define CLIENT_UDP_PORT    "9871"

#define INET_IP_ADDR_LENGTH    (16U)


#define UDP_DGRAM_LEN_MAX    (1024U)
#define MSG_SEND_INTERVAL    (50000)   /* unit: us */

服务器:

void server_init(void)
{
    pid_t pid;
    siginfo_t info;

    int server_sockfd;
    struct sockaddr_in local_addr, remote_addr;

    /* print_addrinfo("ftp"); */   /* domain daytime stream http ftp */
    
    /*____________________________________________________________________________________________*/
    server_sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    if(server_sockfd < 0)
    {
        perror("socket() fail");
        exit(EXIT_FAILURE);
    }

    /* socket_set_reuseaddr(); */

    /*____________________________________________________________________________________________*/
    memset(&local_addr, 0, sizeof(local_addr));

    if(inet_pton(AF_INET, INET_SERVER_IP_ADDR, &(local_addr.sin_addr)) < 0)
    {
        perror("inet_pton() error");
        close(server_sockfd);
        exit(EXIT_FAILURE);
    }
    else
    {
        local_addr.sin_family = AF_INET;
        local_addr.sin_port = htons(atol(SERVER_UDP_PORT));
    }

    if(-1 == bind(server_sockfd, (struct sockaddr *)(&local_addr), sizeof(local_addr)))
    {
        perror("bind() fail");
        close(server_sockfd);
        exit(EXIT_FAILURE);
    }

    /*____________________________________________________________________________________________*/
    char client_addr[INET_IP_ADDR_LENGTH];
    int ret;
    char rcv_buf[UDP_DGRAM_LEN_MAX] = {'\0'};

    memset(&remote_addr, 0, sizeof(remote_addr));
    socklen_t addr_len = sizeof(remote_addr);

    ret = recvfrom(server_sockfd, rcv_buf, UDP_DGRAM_LEN_MAX, 0, (struct sockaddr *)&remote_addr, &addr_len);
    if(-1 == ret)
    {
        perror("recvfrom() failure");
        exit(EXIT_FAILURE);
    }
    else
    {
        if(NULL == inet_ntop(AF_INET, &remote_addr.sin_addr, client_addr, INET_IP_ADDR_LENGTH))
        {
            perror("inet_ntop() error");
        }
        else
        {
            printf("Received %d Bytes From Client: %s (Port: %u)\n", ret, client_addr, ntohs(remote_addr.sin_port));
            printf("%s\n", rcv_buf);
        }
    }

    /*____________________________________________________________________________________________*/
    #if false

    if(inet_pton(AF_INET, INET_CLIENT_IP_ADDR, &(remote_addr.sin_addr)) < 0)
    {
        perror("inet_pton() error");
        exit(EXIT_FAILURE);
    }
    else
    {
        remote_addr.sin_family = AF_INET;
        remote_addr.sin_port = htons(atol(CLIENT_UDP_PORT));
    }

    #endif

    #ifdef SERVER_CONNECT_EN

    if(-1 == connect(server_sockfd, (struct sockaddr *)(&remote_addr), sizeof(remote_addr)))
    {
        perror("connect() fail");
        close(server_sockfd);
        exit(EXIT_FAILURE);
    }
    else
    {
        printf("Successfully Connected To Client-Socket!\n");
    }

    /*____________________________________________________________________________________________*/
    char send_buf[] = {"Of course, I still love you!"};
    if(-1 == send(server_sockfd, send_buf, sizeof(send_buf), 0))
    {
        perror("send() fail");
    }

    #else

    char send_buf[] = {"Of course, I still love you!"};
    if(-1 == sendto(server_sockfd, send_buf, sizeof(send_buf), 0, (struct sockaddr *)(&remote_addr), sizeof(remote_addr)))
    {
        perror("sendto() fail");
    }

    #endif

    /*____________________________________________________________________________________________*/
    sigaction_config();

    /*____________________________________________________________________________________________*/
    pid = fork();

    if(pid < 0)
    {
        perror("fork() error");
    }
    else if(pid == 0)  /* child */
    {
        #ifdef SERVER_CONNECT_EN
        dgram_send(server_sockfd);
        #else
        dgram_sendto(server_sockfd, (struct sockaddr *)(&remote_addr), sizeof(remote_addr));
        #endif
    }
    else  /* parent */
    {
        #ifdef SERVER_CONNECT_EN
        dgram_recv(server_sockfd);
        #else
        dgram_receive(server_sockfd);
        #endif

        if(-1 == waitid(P_PID, 0, &info, WEXITED))
        {
            perror("waitid() failure");
        }

        close(server_sockfd);
        exit(EXIT_SUCCESS);
    }
}

客户端:

void client_init(void)
{
    pid_t pid;
    siginfo_t info;

    int client_sockfd;
    struct sockaddr_in local_addr, remote_addr;

    /*____________________________________________________________________________________________*/
    client_sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(client_sockfd < 0)
    {
        perror("socket() fail");
        exit(EXIT_FAILURE);
    }

    /*____________________________________________________________________________________________*/
    memset(&local_addr, 0, sizeof(local_addr));
    
    local_addr.sin_family = AF_INET;
    local_addr.sin_port = htons(atol(CLIENT_UDP_PORT));
    local_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if(-1 == bind(client_sockfd, (struct sockaddr *)(&local_addr), sizeof(local_addr)))
    {
        perror("bind() fail");
        close(client_sockfd);
        exit(EXIT_FAILURE);
    }

    /*____________________________________________________________________________________________*/
    memset(&remote_addr, 0, sizeof(remote_addr));

    if(inet_pton(AF_INET, INET_SERVER_IP_ADDR, &(remote_addr.sin_addr)) < 0)
    {
        perror("inet_pton() error");
        close(client_sockfd);
        exit(EXIT_FAILURE);
    }
    else
    {
        remote_addr.sin_family = AF_INET;
        remote_addr.sin_port = htons(atol(SERVER_UDP_PORT));
    }

    /*____________________________________________________________________________________________*/
    char send_buf[] = {"Hello World!"};
    int ret;
    
    ret = sendto(client_sockfd, send_buf, sizeof(send_buf), 0, (struct sockaddr *)(&remote_addr), sizeof(remote_addr));

    if(-1 == ret)
    {
        perror("sendto() failure");
        close(client_sockfd);
        exit(EXIT_FAILURE);
    }
    else
    {
        printf("Say \"Hello\" To Server: %s With Port: %s\n", INET_SERVER_IP_ADDR, SERVER_UDP_PORT);
        fflush(stdout);
    }

    /*____________________________________________________________________________________________*/
    char server_addr[INET_IP_ADDR_LENGTH];
    char rcv_buf[UDP_DGRAM_LEN_MAX] = {'\0'};

    memset(&remote_addr, 0, sizeof(remote_addr));
    socklen_t addr_len = sizeof(remote_addr);

    ret = recvfrom(client_sockfd, rcv_buf, UDP_DGRAM_LEN_MAX, 0, (struct sockaddr *)&remote_addr, &addr_len);
    if(-1 == ret)
    {
        perror("recvfrom() failure");
        exit(EXIT_FAILURE);
    }
    else
    {
        if(NULL == inet_ntop(AF_INET, &remote_addr.sin_addr, server_addr, INET_IP_ADDR_LENGTH))
        {
            perror("inet_ntop() error");
        }
        else
        {
            printf("Received %d Bytes From Server: %s (Port: %u)\n", ret, server_addr, ntohs(remote_addr.sin_port));
            printf("%s\n", rcv_buf);
        }
    }

    /*____________________________________________________________________________________________*/
    if(-1 == connect(client_sockfd, (struct sockaddr *)(&remote_addr), sizeof(remote_addr)))
    {
        perror("connect() fail");
        close(client_sockfd);
        exit(EXIT_FAILURE);
    }
    else
    {
        printf("Successfully Connected To Server-Socket!\n");
    }

    /*____________________________________________________________________________________________*/
    sigaction_config();

    /*____________________________________________________________________________________________*/
    pid = fork();

    if(pid < 0)
    {
        perror("fork() error");
    }
    else if(pid == 0)  /* child */
    {
        dgram_send(client_sockfd);
    }
    else  /* parent */
    {
        dgram_recv(client_sockfd);

        if(-1 == waitid(P_PID, 0, &info, WEXITED))
        {
            perror("waitid() failure");
        }

        close(client_sockfd);
        exit(EXIT_SUCCESS);
    }
}

测试:

服务端:

客户端:

参考链接:

https://blog.csdn.net/wanggao_1990/article/details/108020190

 https://blog.csdn.net/qq_29344757/article/details/71616748

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到