网络编程——UDP

来源:互联网 发布:回收站误删恢复软件 编辑:程序博客网 时间:2024/06/01 18:29

先来简单说一下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;}

运行结果

这里写图片描述

原创粉丝点击