UDP协议--网络编程流程

本文深入讲解了UDP协议在网络编程中的应用,包括服务器和客户端的创建、数据收发等核心操作,以及recvfrom和sendto系统调用的具体用法。通过一个完整的示例,展示了如何实现基于UDP的数据交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  UDP是一种无连接的、不可靠的数据报服务。
服务器(被动)
int socket ();//第二个参数选用SOCK_DGRAM
int bind ();//作为服务器,必须将地址信息和sockfd进行绑定
int recvfrom (); //接收任意一个客户端的数据
int sendto (); //给一个客户端发送数据
int close();

客户端(主动)
int socket ();
int sendto ();
int recvfrom ();
int close();

所涉及到的系统调用用法

 ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
 ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);

其余系统调用与TCP协议网络编程流程(博客中有写过)中的一样。

例子
服务器端:

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

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

    struct sockaddr_in ser_addr;
    memset(&ser_addr,0,sizeof(ser_addr));
    ser_addr.sin_family=AF_INET;
    ser_addr.sin_port=htons(6000);
    ser_addr.sin_addr.s_addr=inet_addr("127.0.0.1");

    int res=bind(sockfd,(struct sockaddr*)&ser_addr,sizeof(ser_addr));
    assert(res!=-1);

    while(1)
    {
        char buff[128]={0};
        struct sockaddr_in cli_addr;
        int len=sizeof(cli_addr);

        int n=recvfrom(sockfd,buff,127,0,(struct sockaddr*)&cli_addr,&len);
        if(n<=0)
        {
            printf("recvfrom error\n");
            continue;
        }

        printf("%s:%d-->%s\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.si    n_port),buff);

        int res=sendto(sockfd,"ok",2,0,(struct sockaddr*)&cli_addr,len);
        if(res<=0)
        {
            printf("sendto error\n");
            continue;
        }

    }
    close(sockfd);
    exit(0);
}

客户端:

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

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

    struct sockaddr_in ser_addr;
    memset(&ser_addr,0,sizeof(ser_addr));
    ser_addr.sin_family=AF_INET;
    ser_addr.sin_port=htons(6000);
    ser_addr.sin_addr.s_addr=inet_addr("127.0.0.1");

    while(1)
    {
        printf("input: ");
        char buff[128]={0};
        fgets(buff,127,stdin);
        if(strncmp(buff,"end",3)==0)
        {
            break;
        }

        int res=sendto(sockfd,buff,strlen(buff)-1,0,(struct sockaddr*)&ser_a    ddr,sizeof(ser_addr));
        assert(res!=-1);

        memset(buff,0,128);
        int n=recvfrom(sockfd,buff,127,0,NULL,NULL);
        assert(n!=-1);
        printf("recvfrom data :%s\n",buff);
    }
    close(sockfd);
    exit(0);
}

运行结果如下:
在这里插入图片描述
在这里插入图片描述
特点
一次sendto对应一次recvfrom
接收方一次recvfrom如果没有将一次sendto发送的数据接收完,则剩余的数据就会被丢弃。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值