网络编程——UDP

先来简单说一下UDP协议的相关内容

一、UDP协议

1、UDP协议:UDP与TCP一样,都属于运输层协议,UDP为应用层提供不可靠、无连接的、基于数据报的服务。

2、UDP报头

这里写图片描述

3、UDP与TCP的比较

TCP : 它是一种面向连接的,可靠的,流式服务。
UDP:它是一种无连接的,不可靠的,数据报服务

TCP的“可靠”:TCP协议使用超时重传、数据确认等方式来确保数据包被正确地发送至目的端,因此TCP是可靠的。
UDP的“不可靠”:UDP协议无法保证数据从发送端正确的传送到目的端。如果数据在中途丢失,或者目的端通过数据校验发现数据错误而将其丢弃,则UDP协议只是简单的通知应用程序发送失败。因此,UDP协议的应用程序通常要自己处理数据确认、超时重传等逻辑。

流式服务

这里写图片描述

数据报服务

这里写图片描述

二、使用UDP协议完成网络编程

1、协议选择(本篇博客选择UDP)

TCP协议:它是一种面向连接的,可靠的,流式服务。
UDP协议:它是一种无连接,不可靠的,数据报服务。

2、UDP的编程流程:

ser(服务器端):socket、 bind、 recvfrom/sendto、 close
cli(客户端):socket、 sendto/recvfrom、 close

接下来说一下用到的函数(socket与close在这里就不介绍了)

a. int recvfrom(int sockfd, void buff, int len, int flag, struct sockaddr *src_addr, int addr_len);
buff:指定缓冲区的位置
len:指定缓冲区的大小
src_addr:发送端的socket地址
addr_len:发送端socket地址的长度

b. int sendto(int sockfd, void *buff, int len, int flag, struct sockaddr*dest_addr, int addr_len);
buff:指定缓冲区的位置
len:指定缓冲区的大小
dest_addr:接收端的socket地址
addr_len:接收端socket地址的长度

代码实现

ser.c

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

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

    struct sockaddr_in ser,cli;
    ser.sin_family = AF_INET;
    ser.sin_port = htons(6000);
    ser.sin_addr.s_addr = inet_addr("127.0.0.1");

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

    while(1)
    {
        char buff[128] = {0};
        int len = sizeof(cli);
        recvfrom(sockfd,buff,127,0,(struct sockaddr*)&cli,&len);
        printf("IP::%s\nPORT::%d\nDATA::%s\n",inet_ntoa(cli.sin_addr),ntohs(cli.sin_port),buff);
        sendto(sockfd,"I know",sizeof("I know"),0,(struct sockaddr*)&cli,len);
    }

    close(sockfd);

    return 0;

}

cli.c

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

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

    struct sockaddr_in ser,cli;
    ser.sin_family = AF_INET;
    ser.sin_port = htons(6000);
    ser.sin_addr.s_addr = inet_addr("127.0.0.1");

    char buff[128] = {0};
    printf("buff\n");
    sendto(sockfd,"hello world!",sizeof("hello world!"),0,(struct sockaddr*)&ser,sizeof(ser));
    sendto(sockfd,"hello world!",sizeof("hello world!"),0,(struct sockaddr*)&ser,sizeof(ser));

    recvfrom(sockfd,buff,127,0,NULL,NULL);
    printf("%s\n",buff);

    close(sockfd);

    return 0;

}

运行结果

这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值