ipv6例程-udp

版权声明:转载请标明出处。

本篇为记录linux socket支持ipv6的学习笔记。

udp服务端程序:

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

int main(int argc, char **argv)
{
    struct sockaddr_in6 s_addr;
    struct sockaddr_in6 c_addr;
    int sock;
    socklen_t addr_len;
    int len;
    char buff[128];
    char buf_ip[128];

    if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) == -1) {
        perror("socket");
        exit(errno);
    } else
        printf("create socket.\n\r");
    memset(&s_addr, 0, sizeof(struct sockaddr_in6));
    s_addr.sin6_family = AF_INET6;

    if (argv[2])
        s_addr.sin6_port = htons(atoi(argv[2]));
    else
        s_addr.sin6_port = htons(4444);

    if (argv[1])
        inet_pton(AF_INET6, argv[1], &s_addr.sin6_addr);
    else
        s_addr.sin6_addr = in6addr_any;

    s_addr.sin6_port = htons(12344);
    s_addr.sin6_addr = in6addr_any;
    int on = 1;
    //if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0)
    //{
    //      perror("setsockopt");
    //          return -1;
    //}
    if ((bind(sock, (struct sockaddr *) &s_addr, sizeof(s_addr))) == -1) {
        perror("bind");
        exit(errno);
    } else
        printf("bind address to socket.\n\r");

    addr_len = sizeof(c_addr);
    while (1) {
        len = recvfrom(sock, buff, sizeof(buff) - 1, 0,
                (struct sockaddr *) &c_addr, &addr_len);
        if (len < 0) {
            perror("recvfrom");
            exit(errno);
        }

        buff[len] = '\0';
        printf("receive from %s: buffer:%s\n\r",
                inet_ntop(AF_INET6, &c_addr.sin6_addr, buf_ip, sizeof(buf_ip)),
                buff);
    }
    return 0;
}

upd客户端程序:

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>


static char src[] = "fe80::20c:29ff:fed2:4aff";
static char dst[] = "fe80::20c:29ff:fef4:40f";
void main(int argc, char **argv)
{
    int udp6_socket, ret, ttl, on, addr_len;
    struct sockaddr_in6 saddr;
    struct sockaddr_in6 daddr;
    memset(&daddr,0,sizeof(struct sockaddr_in6));
    char buffer[] = "Hello World6";


    if ((inet_pton(AF_INET6, (char *)&dst[0], &daddr.sin6_addr)) != 1)
    {
        printf("invalid ipv6 addr \r\n");
        return ;
    }
    
    addr_len = sizeof(struct sockaddr_in6);
    
    daddr.sin6_family = AF_INET6;
    daddr.sin6_port = htons(12345);

    /* 创建IPv6套接字,IPv6使用AF_INET6 */
    udp6_socket = socket(AF_INET6, SOCK_DGRAM, 0);
    if (udp6_socket == -1)
    {
        printf("create udp6_socket fail\r\n");
        return;
    }

//  if (setsockopt(udp6_socket, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0)
//  {
//      perror("setsockopt");
//      return ;
//  }

    /* 发送 */
    ret = sendto(udp6_socket, &buffer[0], sizeof(buffer), 0, (struct sockaddr *)&daddr, addr_len);
    if (ret > 0){
        printf("udp6 send %d bytes success \r\n", ret);
    }else{
        perror("send error");
    }

    /* 关闭套接字 */
    close(udp6_socket);
    return;
}

 

与ipv6的tcp socket相比,upd不需要绑定网卡就可以进行通信了。

注意:记得设置ipv6防火墙ip6tables,把端口的权限打开,否则可能两台不同的机器会无法通信。

猜你喜欢

转载自blog.csdn.net/weixin_40292830/article/details/85028206
今日推荐