UDP通信(服务器-客户端)

news/2024/5/18 14:00:56 标签: udp, 网络协议, 网络, 服务器, tcp/ip, linux

     一、 UDP服务器-客户端通信

  UDP(User Datagram Protocol)是一种面向无连接的传输层协议,它提供了一种简单的、不可靠的数据传输服务。与TCP(Transmission Control Protocol)不同,UDP不建立连接,也不保证数据的可靠性和顺序传输。UDP被广泛用于那些对数据传输延迟要求较高,且能够容忍一定数据丢失的应用场景,如实时音视频传输、在线游戏等。 

#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);
    - 参数:
        - sockfd : 通信的fd
        - buf : 要发送的数据
        - len : 发送数据的长度
        - flags : 0
        - dest_addr : 通信的另外一端的地址信息
        - addrlen : 地址的内存大小


ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
    - 参数:
        - sockfd : 通信的fd
        - buf : 接收数据的数组
        - len : 数组的大小
        - flags : 0
        - src_addr : 用来保存另外一端的地址信息,不需要可以指定为NULL
        - addrlen : 地址的内存大小

 二、UDP通信时,服务器为什么不使用多进程或多线程处理?

        UDP是一种面向无连接的协议,与TCP不同,它在传输层不维护连接状态因此,UDP服务器在接收到UDP数据包时,并不需要为每个客户端创建新的进程或线程来处理连接。这是因为UDP通信是无连接的,每个数据包都是独立的,服务器可以直接处理接收到的数据包,而无需维护连接状态。

对比一下:

  • TCP(传输控制协议): TCP是面向连接的协议,它在通信双方之间建立连接,保持连接状态,并提供可靠的、有序的数据传输。在TCP通信中,服务器通常需要为每个客户端连接创建新的进程或线程,以处理多个客户端同时发起的连接请求,并在连接期间保持状态。

  • UDP(用户数据报协议): UDP是无连接的协议,每个UDP数据包都是独立的,没有连接状态的维护。服务器在接收UDP数据包时,不需要为每个客户端连接创建额外的进程或线程,因为它不必保持连接状态。每个数据包都包含足够的信息,服务器可以直接处理它们,而不必关心连接的保持。

        总的来说,UDP适用于那些对实时性要求高、能够容忍一定数据丢失的场景,因为它的无连接性和较低的开销使其更适合快速而简单的通信。在这样的场景下,服务器可以轻松地处理多个客户端的独立请求,而无需为每个连接创建额外的进程或线程。

三、服务器客户端代码

服务器


#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>



int main(){

    // 创建一个通信的socket
    int fd =socket(PF_INET,SOCK_DGRAM,0);
    if(fd ==-1){
        perror("socket");
        exit(-1);
    }

    struct sockaddr_in addr;
    addr.sin_family =AF_INET;
    addr.sin_port = htons(9999);
    addr.sin_addr.s_addr = INADDR_ANY;
    // 绑定
    int ret = bind(fd,(struct sockaddr *)&addr,sizeof(addr));
    if(ret==-1){
        perror("bind");
        exit(-1);
    }

    while (1){

        char recvbuf[128];
        char ipbuf[16];
        struct sockaddr_in cliaddr;
        int len =sizeof(cliaddr);

        // 接受数据
        int num =recvfrom(fd,recvbuf,sizeof(recvbuf),0,(struct sockaddr *)&cliaddr,&len);
        if(num==-1){
            perror("recvfrom");
            exit(-1);
        }
        printf("client IP is : %s , Port is %d", inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ipbuf,sizeof (ipbuf)),
               ntohs(cliaddr.sin_port));

        printf("client say %s\n",recvbuf  );
        // 发生数据
        sendto(fd,recvbuf, strlen(recvbuf)+1,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));


    }

    close(fd);
    return 0;
}

客户端


#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>



int main(){

    // 创建一个通信的socket
    int fd =socket(PF_INET,SOCK_DGRAM,0);
    if(fd ==-1){
        perror("socket");
        exit(-1);
    }

    struct sockaddr_in saddr;
    saddr.sin_family =AF_INET;
    saddr.sin_port = htons(9999);
    inet_pton(AF_INET,"127.0.0.1",&saddr.sin_addr.s_addr);
//    // 绑定
//    int ret = bind(fd,(struct sockaddr *)&addr,sizeof(addr));
//    if(ret==-1){
//        perror("bind");
//        exit(-1);
//    }

    while (1){

        char sendbuf[128];
        int i=0;
        sprintf(sendbuf,"hello, i am a client %d\n",i++);
        sendto(fd,sendbuf, strlen(sendbuf)+1,0,(struct sockaddr *)&saddr,sizeof(saddr));




//        char ipbuf[16];
//        struct sockaddr_in cliaddr;
//        int len =sizeof(cliaddr);

        // 接受数据
        int num =recvfrom(fd,sendbuf,sizeof(sendbuf),0,NULL,NULL);
        if(num==-1){
            perror("recvfrom");
            exit(-1);
        }

        printf("SERVER say %s\n",sendbuf);
        // 发生数据
        sleep(1);


    }

    close(fd);
    return 0;
}


http://www.niftyadmin.cn/n/5300982.html

相关文章

【c语言】飞机大战终

效果展示 效果演示 源码展示 #include<stdio.h> #include <graphics.h> #include <assert.h> #include <stdlib.h> #include<conio.h>//_getch(); #include <time.h> #include <math.h> #include<mmsystem.h>//包含多媒体设备…

Apisix常见问题

1.通过接口操作路由时X-API-KEY cd /usr/local/apisix/conf vim config-default.yaml注释掉这一部分 #allow_admin: # http://nginx.org/en/docs/http/ngx_http_access_module.html#allow# - 0.0.0.0/24 # If we dont set any IP list, then a…

使用(C++)QT实现经典小游戏(俄罗斯方块)

一、简介 学习QT有段时间了&#xff0c;但是也没用来做过啥&#xff0c;这两日就突然想到了这个游戏&#xff0c;于是就打算用QT写一个&#xff0c;也不是纯纯自己写的代码&#xff0c;在写之前我也是找了几个别人的项目看了一下&#xff0c;学习了框架的搭建&#xff0c;和某些…

《工具录》nslookup

工具录 1&#xff1a;nslookup2&#xff1a;选项介绍3&#xff1a;示例 - 命令行模式3.1&#xff1a;查询类型设置3.2&#xff1a;指定 DNS 服务器 4&#xff1a;示例 - 交互模式5&#xff1a;其他 本文以 kali-linux-2023.3-vmware-amd64 为例。 1&#xff1a;nslookup nsloo…

openmediavault(OMV) (25)在线网盘(3)owncloud

简介 OwnCloud是一种开源的文件同步和共享解决方案,它允许你在自己的服务器上创建个人云存储服务。通过OwnCloud,你可以上传、同步、共享和访问文件,以及使用其他功能如日历、联系人管理等。 以下是OwnCloud的一些特点和功能: 文件同步和共享:OwnCloud提供了跨多个设备…

Doris数仓开发规范

文章目录 一、字符集规范二、建表规范三、数据变更规范四、数据查询规范结尾 一、字符集规范 【强制】数据库字符集指定utf-8&#xff0c;并且只支持utf-8。 二、建表规范 【建议】库名统一使用小写方式&#xff0c;中间用下划线&#xff08;_&#xff09;分割&#xff0c;长…

js文件上传 分片上传/断点续传/极速秒传

(极速秒传)利用md5判断上传的文件是否存在 MD5信息摘要算法&#xff0c;一种被广泛使用的密码散列函数&#xff0c;可以产生出一个128位&#xff08;16字节&#xff09;的散列值&#xff08;hash value&#xff09;&#xff0c;用于确保信息传输完整一致。 每一个文件都会生成…

前端工作细节提升总结

工作不光是在完美的环境下进行的&#xff0c;设计好的页面&#xff0c;已经完善的需求&#xff0c;理想的工期&#xff0c;合作完美的小伙伴。实际上有设计稿的可能都不是很多&#xff0c;需求也是一边做一边完善&#xff0c;时间还挺紧张&#xff0c;小伙伴可能还会跟你产生冲…