Linux网络编程 之 UDP编程(六)

目录
1. UDP客户端
    核心函数
    完整的UDP客户端程序
2. UDP服务端
    核心函数
    完整的UDP客户端程序
3. 总结


1. UDP客户端

核心函数

ssize_t sendto(int sockfd,
                const void *buf,
                size_t nbytes,
                int flags,
                socklen_t addrlen );
  • sockfd:套接字
  • buf:发送数据缓冲区
  • nbytes:发送数据缓冲区的大小
  • flags:一般为 0
  • to:指向目的主机地址结构体的指针
  • addrlen:to 所指向内容的长度

完整的UDP客户端程序

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <unistd.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>  

int main(int argc, charchar *argv[])  
{  
    unsigned short port ;
    charchar *server_ip ;

    if( argc > 1 )   // main函数传参,服务器ip地址  
    {     
        server_ip = argv[1];  
    }  

    if( argc > 2 )   // main函数传参,服务器端口  
    {  
        port = atoi(argv[2]);  
    }  

    int sockfd;  
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);   //创建UDP套接字  
    if(sockfd < 0)  
    {  
        perror("socket");  
        exit(-1);  
    }  

    // 构造套接字地址  这个结构体有三个参数:套接字域,ip,port
    struct sockaddr_in dest_addr;  
    bzero(&dest_addr, sizeof(dest_addr));   // 清空内容  
    dest_addr.sin_family = AF_INET;     // ipv4  
    dest_addr.sin_port   = htons(port); // 端口转换  
    inet_pton(AF_INET, server_ip, &dest_addr.sin_addr); // ip地址转换  

    printf("send data to UDP server %s:%d!\n", server_ip, port);  

    while(1)  
    {  
        char send_buf[512] = "";  
        fgets(send_buf, sizeof(send_buf), stdin);//获取输入  
        send_buf[strlen(send_buf)-1] = '\0';  
        //发送数据  
        int len = sendto(sockfd, send_buf, strlen(send_buf), 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));  
        printf("len = %d\n", len);  
    }  

    close(sockfd);  
    return 0;  
}

2. UDP 服务端

核心函数:

接收端使用 bind() 函数,来完成地址结构与 socket 套接字的绑定,这样 ip、port 就固定了

int bind( int sockfd,
          const struct sockaddr *myaddr,
          socklen_t addrlen );
  • sockfd: socket 套接字
  • myaddr: 服务端的地址结构指针
  • addrlen:该地址结构的长度

recvfrom方法接收 UDP 数据,并将源地址信息保存在 from 指向的结构中

ssize_t recvfrom(   int sockfd, 
                    void *buf,    
                    size_t nbytes,
                    int flags,
                    struct sockaddr *from, 
                    socklen_t *addrlen );

参数的含义,可以参考UDP客户顿的sendto方法:

完整的UDP服务端程序

    #include <stdio.h>  
    #include <stdlib.h>  
    #include <string.h>  
    #include <unistd.h>  
    #include <sys/socket.h>  
    #include <netinet/in.h>  
    #include <arpa/inet.h>  
    int main(int argc, charchar *argv[])  
    {  
        unsigned short port ;     // 本地端口  
        if(argc > 1)  
        {  
            port = atoi(argv[1]);  
        }  

        int sockfd;  
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);    // 创建套接字  
        if(sockfd < 0)  
        {  
            perror("socket");  
            exit(-1);  
        }  

        // 构造本地网络地址的结构体  sockaddr_in
        struct sockaddr_in my_addr;  
        bzero(&my_addr, sizeof(my_addr));   // 清空结构体内容  
        my_addr.sin_family = AF_INET;   // ipv4  
        my_addr.sin_port   = htons(port);   // 端口转换  
        my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 绑定网卡所有ip地址,INADDR_ANY为通配地址,值为0  

        printf("Binding server to port %d\n", port);  
        int err_log;  
        //将套接字绑定到本地网络地址结构体上
        err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));   
        if(err_log != 0)  
        {  
            perror("bind");  
            close(sockfd);        
            exit(-1);  
        }  

        printf("receive data...\n");  
        while(1)  
        {  
            int recv_len;  
            char recv_buf[512] = "";  
            struct sockaddr_in client_addr;  
            char cli_ip[INET_ADDRSTRLEN] = "";//INET_ADDRSTRLEN=16  
            socklen_t cliaddr_len = sizeof(client_addr);   

            // 接受数据  
            recv_len = recvfrom(sockfd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr*)&client_addr, &cliaddr_len);  
            inet_ntop(AF_INET, &client_addr.sin_addr, cli_ip, INET_ADDRSTRLEN);  
            printf("\nip:%s ,port:%d\n",cli_ip, ntohs(client_addr.sin_port));  
            printf("data(%d):%s\n",recv_len,recv_buf);  
        }  

        close(sockfd);  
        return 0;  
    }  

3. 总结

UDP服务端编程分5步:

  1. 创建 UDP socket套接字,用socket函数。

  2. 设置socket的属性,用setsockopt()函数,(可选)

  3. 往socket绑定包含 IP信息,地址信息的 struct sockaddr_in(IPv4)结构体。用bind()函数

  4. 循环接收消息,用recvfrom()函数

  5. 关闭socket套接字

UDP客户端编程分:

  1. 创建 UDP socket套接字,用socket函数。

  2. 用sendto()函数往指定的IP,地址发送信息。

猜你喜欢

转载自blog.csdn.net/qq_33394088/article/details/80918783