Linux下的网络编程(二)UDP编程

来源:互联网 发布:海量数据库解决方案 编辑:程序博客网 时间:2024/06/15 15:08

UDP协议(用户数据报协议):它为应用层提供不可靠、无连接和基于数据报的服务。“不可靠”意味着UDP协议无法保证数据从发送端正确地传送到目的端。如果数据早中途丢失,或者目的端通过数据校验发现数据错误而将其丢弃,则UDP协议只是简单地通知应用程序发送失败。因此,使用UDP协议的应用程序通常要自己处理数据确认、超时重传等逻辑。UDP协议是无连接的,即通信双方不保持一个长久的联系,因此应用程序每次发送数据都要明确指定接收端的地址。基于数据的服务,是相对于基于流的服务而言的。每个UDP数据报都有一个长度,接收端必须以该长度为最小单位将其所有内容一次性读出,否则数据将被截断。


UDP报头:



UDP优点与缺点:节省时间、速度快、不需要内核开辟额外空间来维持连接,缺点是数据易丢失,不安全。

TCP字节流服务与UDP数据报服务区别:

流式服务:发送端执行的写操作次数和接收端执行的读操作次数之间没有任何数量关系。

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


UDP 的编程流程:
服务器: socket       bind             recvfrom/sendto            close
客户端: socket                   sendto/recvfrom            close

int recvfrom(int sockfd, void *buff, int len, int flag,struct sockaddr *src_addr(源端口号), int * addr_len);

int sendto(int sockfd, void *buff, int len, int flag,struct sockaddr*dest_addr(目的端口号), int addr_len);


以下是UDP网络编程:

服务器端:

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<assert.h>#include<sys/types.h>#include<sys/socket.h>#include<arpa/inet.h>void 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);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,"ok",2,0,(struct sockaddr*)&cli,len);close(sockfd);}

客户端:

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<assert.h>#include<sys/types.h>#include<sys/socket.h>#include<arpa/inet.h>void 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");sendto(sockfd,"hello world",11,0,(struct sockaddr*)&ser,sizeof(ser));char buff[128]={0};recvfrom(sockfd,buff,127,0,NULL,NULL);printf("OK\n");close(sockfd);}
执行结果如下: