【Linux】UDP编程流程

UDP的读写接口

 recvfrom()读取套接字上的数据,

ssize_t recvfrom(int sockfd, void *buff, size_t len, int flags,struct sockaddr* src_addr, socklen_t *addrlen);
//(套接字,读缓冲区位置,大小,0,记录发送端套接字地址,该地址长度)

sendto()发送

ssize_t sendto(int sockfd, void *buff, size_t len, int flags,struct sockaddr* dest_addr, socklen_t addrlen);

UDP协议:无连接 不可靠(丢了不做额外处理) 数据报

发送端应用程序每执行一次写操作, UDP 模块就将其封装成一个 UDP 数据报发送。接收端必须及时针对每一个 UDP 数据报执行读操作,否则就会丢包。
并且,如果用户没有指定足够的应用程序缓冲区来读取 UDP 数据,则 UDP 数据将被截断

它可以接收所有客户端发送给当前应用程序的数据,不只能接收某一个客户端的数据,它没有三次握手和四次挥手。

UDP没有粘包,如果一次没读完,剩下的数据就丢弃了

netstat -nap看端口

tcp和udp可以用一个端口(协议不一样)


 UDP服务端代码

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

int main()
{
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);//创建套接字
    assert( sockfd != -1 );
    struct sockaddr_in saddr,caddr;//因为没有连接,所以要能确定自己的地址和客户端的地址
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(6000);
    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));//绑定端口ip
    assert( res != -1 );

    while( 1 )
    {
        int len = sizeof(caddr);
        char buff[128] = {0};
        recvfrom(sockfd,buff,127,0,(struct sockaddr*)&caddr,&len);//接收数据,caddr装客户端地址
        printf("ip:%s,port:%d,buff=%s\n",inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port),buff );//打印数据

        sendto(sockfd,"ok",2,0,(struct sockaddr*)&caddr,sizeof(caddr));//反馈数据
    }

    close(sockfd);
}

UDP客户端代码

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

int main()
{
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);//ipv4,UDP
    assert( sockfd != -1 );

    struct sockaddr_in saddr;//服务端地址
    memset(&saddr,0,sizeof(saddr));//清空
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(6000);
    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    while( 1 )
    {
        char buff[128] = {0};
        printf("input:\n");

        fgets(buff,128,stdin);//输入要传输的数据

        if ( strncmp(buff,"end",3) == 0 )//如果是end,关闭
        {
            break;
        }
        sendto(sockfd,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(saddr));//发送
        memset(buff,0,128);

        int len = sizeof(saddr);
        recvfrom(sockfd,buff,127,0,(struct sockaddr*)&saddr,&len);//接收服务端数据

        printf("buff=%s\n",buff);
    }

    close(sockfd);//关闭套接字
}

可以同时接收多个客户端的数据。即使服务端关闭再开启,客户端仍然可以发送数据。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曦樂~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值