• Linux下udp编程


    一、函数

    1、recvfrom函数

    UDP使用recvfrom()函数接收数据,他类似于标准的read(),但是在recvfrom()函数中要指明目的地址。

    #include <sys/types.h>
    #include <sys/socket.h>
    
    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                            struct sockaddr *src_addr, socklen_t *addrlen);
    //返回发送数据的长度 -非0成功   -1-失败

    2、sendto函数

    UDP使用sendto()函数发送数据,他类似于标准的write(),但是在sendto()函数中要指明目的地址

    #include <sys/types.h>
    #include <sys/socket.h>
    
    ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                          const struct sockaddr *dest_addr, socklen_t addrlen);
    //返回发送数据的长度 -非0成功   -1-失败

    3、socket函数

    #include <sys/types.h>
    #include <sys/socket.h>
    
    //函数原型
    int socket(int domain, int type, int protocol);

    为了执行网络输入输出,一个进程必须做的第一件事就是调用socket函数获得一个文件描述符。

    第一个参数指明了协议簇,目前支持5种协议簇,最常用的有AF_INET(IPv4协议)和AF_INET6(IPv6协议)。

    第二个参数指明套接字类型,有三种类型可选:SOCK_STREAM(字节流套接口)、SOCK_DGRAM(数据报套接口)和SOCK_RAW(原始套接口);TCP一般选择SOCK_STREAM,而UDP选择SOCK_DGRAM。

    4、bind函数

    #include <sys/types.h>
    #include <sys/socket.h>
    
    int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

    第一个参数是socket函数返回的套接字的文件描述符。第二和第三个参数分别是一个指向特定于协议的地址结构的指针和该地址结构的长度。

    5、sockaddr_in

    #include <netinet/in.h>
    #include <arpa/inet.h>
    struct
    sockaddr_in { sa_family_t sin_family; //地址族(Address Family) uint16_t sin_port ; //16位 TCP/IP 端口号 struct in_addr sin_addr; //32位 IP 地址 char sin_zero[8]; };

    二、server.c

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<errno.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<netinet/ip.h>
    #include<unistd.h>
    #include<arpa/inet.h>
    #include <sys/time.h>    
    #include <unistd.h>
    
    #define UDP_PORT  8080
    #define UDP_BUF_SIZE  100
    #define UDP_SERV_IP_ADDR  "192.168.100.178"
    #define UDP_CLIENT_IP_ADDR  "192.168.100.51"
    
    
    int
    main(void)
    {
        int fd = -1;
        int len = 0;
        int res = 0;
        int i;
        struct sockaddr_in sin;
    
        /*  创建socket_fd   */
        if((fd = socket( AF_INET, SOCK_DGRAM , 0)) < 0)
        {
            printf("*******SOCKET********
    ");
            return -1;
        }
        
        /*  允许绑定地址快速重用   */
        int b_reuse = 1;
        setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof(b_reuse));
    
        /*   填充struct sockaddr_in 结构体变量   */
        bzero( &sin, sizeof(sin));
        sin.sin_family = AF_INET;
        sin.sin_port = htons(UDP_PORT);
        /*  让服务器程序能绑定在任意的IP上    */
    #if    1
        sin.sin_addr.s_addr = htonl(INADDR_ANY);//绑定任何主机上ip地址
    #else
        if((inet_pton(AF_INET, UDP_SERV_IP_ADDR, (void *)&sin.sin_addr)) < 0)
        {
            printf("******INET_PTON*******
    ");
            return -1;
        }
    #endif
        /*  绑定  */
        if(bind (fd, (struct sockaddr *)&sin, sizeof(sin)) <0 )
        {
            printf("*******bind*******
    ");
            return -1;
        }
    
    
        char buf[UDP_BUF_SIZE];
        struct sockaddr_in cin;
        socklen_t addrlen = sizeof(cin);
    
        while(1)
        {
            bzero(buf ,UDP_BUF_SIZE);     

          memset(buf,0,sizeof(buf));

          len=0;

              len = recvfrom(fd, buf, UDP_BUF_SIZE-1,0,(struct sockaddr*)&cin, &addrlen);

         if(len > 0)
            {
                char ipv4_addr[16];
                if(!inet_ntop(AF_INET, (void *)&cin.sin_addr, ipv4_addr, sizeof(cin)))
                {
                    printf("*******inet_ntop********
    ");
                    return -1;
                }
    
                printf("********recv from (%s:%d), date:",ipv4_addr, ntohs(sin.sin_port));
                
                for(i = 0;i< len;i++)
                  printf("%02X ", buf[i]);
                printf("
    ");
            }
        sendto(fd,buf,len,0,(struct sockaddr*)&cin, addrlen); } close(fd);
    return 0; }
  • 相关阅读:
    第四章:Django模型——添加 Event发布会的表 报错
    第四章:Django模型——admin后台管理
    第四章:Django 模型 —— 设计系统表
    第三章:3.9 清除 Google 浏览器中的缓存
    第三章:3.9 关上窗户
    第三章:3.9 引用Django 认证登陆
    第三章:3.8 登陆 Django 默认后台
    降脂食物
    决定孩子人生高度的,不是知识而是这个!
    百万保险
  • 原文地址:https://www.cnblogs.com/listxue/p/13141095.html
Copyright © 2020-2023  润新知