1404|3

12

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【米尔T113测评】UDP编程 [复制链接]

 

udp --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议。
udp不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。
udp在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。
udp是一种面向无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。

udp通讯流程很简单,具体步骤如下:

 
udp服务端代码
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdbool.h>
#include <pthread.h>

#define BUFFER_SIZE 1024 // buf size

struct CONNECT_INFO {
    struct sockaddr_in client_addr;
};

static int sock_fd;
static volatile bool is_connect = false;

bool udp_server_init(short port) {
    struct sockaddr_in server_addr;

    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock_fd == -1) {
        perror("socket");
        return false;
    }

    // initialize address.
    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    // bind the local port.
    if ((bind(sock_fd, (struct sockaddr *)&server_addr, 
                            sizeof(struct sockaddr_in))) == -1) {
        perror("bind");
        return false;
    }

    return true;
}

void *send_thread(void *arg) {
    struct CONNECT_INFO *info = (struct CONNECT_INFO *)arg;
    if (info == NULL) {
        printf("error connect info");
        return (void*)-1;
    }

    while (1) {
        char send_buf[BUFFER_SIZE];
        bzero(send_buf, sizeof(send_buf));

        // input from keyboard.
        char *str = fgets(send_buf, sizeof(send_buf), stdin);
        if (str == NULL) {
            perror("fgets");
            continue;
        }
        if (strlen(str) <= 1) {
            continue;
        }

        if(is_connect == false) {
            printf("No client are available!\n");
            continue;
        }

        // send data.
        if ((sendto(sock_fd, send_buf, strlen(str) - 1, 0,
                        (struct sockaddr *)&info->client_addr,
                        sizeof(struct sockaddr_in))) < 0) {
            perror("sendto");
            continue;
        }
    }

    return (void*)0;
}

int main(int argc, char *argv[]) {
    // check your input.
    if (argc != 2) {
        printf("Usage:\n");
        printf("    %s <port number>\n", argv[0]);
        return -1;
    }

    short port = atoi(argv[1]);

    bool ret = udp_server_init(port);
    if (ret == false) {
        goto err;
    }

    pthread_t t_id;
    struct CONNECT_INFO info;
    socklen_t addr_len = sizeof(struct sockaddr_in);

    memset(&info, 0, sizeof(info));

    pthread_create(&t_id, NULL, send_thread, (void *)&info);
    pthread_detach(t_id);

    printf("Waiting for client connectionn\n");
    while (1) {
        // recive from client.
        char recv_buf[BUFFER_SIZE];
        bzero(recv_buf, sizeof(recv_buf));
        if ((recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0,
                        (struct sockaddr *)&info.client_addr, &addr_len)) <= 0) {
            perror("recvfrom");
            goto err;
        }

        printf("[Recv from client %s:%d] : %s\n",
                inet_ntoa(info.client_addr.sin_addr),
                htons(info.client_addr.sin_port),
                recv_buf);
        
        is_connect = true;
    }

    close(sock_fd);
    return 0;

err:
    close(sock_fd);
    return -1;
}

 

 

udp客户端代码:

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

#define BUFFER_SIZE 1024 // buf size

int main(int argc, char *argv[]) {
    // check the arguments.
    if (argc != 3) {
        printf("Usage:\n");
        printf("    %s <server_addr> <portnumber>\n", argv[0]);
        return -1;
    }

    int sock_fd;
    char send_buf[BUFFER_SIZE];
    char recv_buf[BUFFER_SIZE];
    struct sockaddr_in server_addr;

    char *addr = argv[1];
    short port = atoi(argv[2]);

    // initialize address.
    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(addr);
    server_addr.sin_port = htons(port);

    // create udp socket.
    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock_fd == -1) {
        perror("socket");
        return -1;
    }

    pid_t pid = fork();
    if (pid > 0) {
        // The parent process is responsible for sending messages.
        while (1) {
            bzero(send_buf, sizeof(send_buf));    

            // read from stdin.
            char *str = fgets(send_buf, sizeof(send_buf), stdin);
            if (str == NULL) {
                perror("fgets");
                goto err;
            }
            if (strlen(str) <= 1) {
                continue;
            }

            // send data.
            if ((sendto(sock_fd, send_buf, strlen(str) - 1, 0,
                            (struct sockaddr *)&server_addr,
                            sizeof(struct sockaddr_in))) < 0) {
                perror("sendto");
                goto err;
            }
        }
    }
    else if (pid == 0) {
        // The child process is responsible for receiving messages.
        while (1) {
            bzero(recv_buf, sizeof(recv_buf));
            socklen_t addr_len = sizeof(struct sockaddr_in);
            if ((recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0,
                            (struct sockaddr *)&server_addr,
                            &addr_len)) <= 0) {
                perror("recvfrom");
                goto err;
            }

            printf("[Recv from server %s:%d] : %s\n",
                    inet_ntoa(server_addr.sin_addr),
                    htons(server_addr.sin_port),
                    recv_buf);
        }
    }

    close(sock_fd);
    return 0;

err:
    close(sock_fd);
    return -1;
}

 

编译后运行结果:

 

 

 

 

 

 

最新回复

设置对应端口号呗,广播模式,恶意的攻击确实防不住。   详情 回复 发表于 2023-9-6 14:38
点赞 关注
 
 

回复
举报

7196

帖子

2

TA的资源

版主

沙发
 

想要广播又想要可靠性,用什么技术比较好?

点评

关键是开放了端口,被扫到,如何应对广播风暴?  详情 回复 发表于 2023-9-6 11:06
 
 
 

回复

6992

帖子

11

TA的资源

版主

板凳
 
wangerxian 发表于 2023-9-5 16:47 想要广播又想要可靠性,用什么技术比较好?

关键是开放了端口,被扫到,如何应对广播风暴?

点评

设置对应端口号呗,广播模式,恶意的攻击确实防不住。  详情 回复 发表于 2023-9-6 14:38
 
 
 

回复

7196

帖子

2

TA的资源

版主

4
 
lugl4313820 发表于 2023-9-6 11:06 关键是开放了端口,被扫到,如何应对广播风暴?

设置对应端口号呗,广播模式,恶意的攻击确实防不住。

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表