UDP编程应用探讨一

来源:互联网 发布:黑马python百度云 编辑:程序博客网 时间:2024/06/05 19:59

由于在项目中用TCP比较多,也发现TCP在频繁数据传输的应用中存在拥塞的缺点。考虑到UDP在这方面存在优点,抽出时间专门测试一下UDP的编程使用和TCP的区别,以使下次设计应用层协议时正确选择传输层协议


1、 UDP每次操作都是针对一个数据包,而TCP操作数据流

发送方调用3sendto 发送大小都为64B 的数据包:

数据包Aa_HelloWorld

数据包Bb_HelloWorld

数据包Cc_HelloWorld

 

情况一

接收方调用2recvfrom 

接收长度参数为4时:

1次,接收到数据包Aa_He

2次,接收到数据包Bb_He

 

情况二

接收方调用3recvfrom

接收长度参数为1024

1次,接收到数据包Aa_HelloWorld

2次,接收到数据包Bb_HelloWorld

3次,接收到数据包Cc_HelloWorld

 

上述两种情况与TCP有很大区别,

第一种情况,若是TCP调用2recv,接收大小为4

将会接收到“a_HelloW”,剩下的数据将留着socket的接收缓存中

而在UDP中,仅数据包C留着socket接收缓存中

 

第二种情况,若是TCP调用3recv,接收大小为1024

仅第1次即会把3个数据包接收完,第23次调用都不会接收到数据(阻塞或接收0个)。

 

2、 发送速率 大于 接收速率

发送端每1s调用sendto发送数据包A到接收端,而接收端每3秒调用recvfrom接收数据包A。此时当接收缓存满时,接收端将出现掉包的情况。但发送端和接收端都是不知道丢包发生了的。

 

3、 UDP协议中有校验和(2B

用于增加传输的可靠性,校验和不对将丢包(并不重传)



//接收端源文件#include<stdio.h>#include<stdlib.h>#include<stdbool.h>#include<string.h>#include<netinet/in.h>#include<sys/socket.h>int main(void){int rsck = socket(AF_INET, SOCK_DGRAM, 0);if(rsck < 0){perror("socket");return -1;}struct sockaddr_in r_addr, s_addr;int r_len = sizeof(r_addr);int s_len = sizeof(s_addr);bzero(&r_addr, r_len);r_addr.sin_family = AF_INET;r_addr.sin_port = htons(5678);r_addr.sin_addr.s_addr = INADDR_ANY;//inet_addr("192.168.1.124");int sinsize = 1;setsockopt(rsck, SOL_SOCKET, SO_REUSEADDR, &sinsize, sizeof(int));int ret = bind(rsck, (struct sockaddr*)&r_addr, r_len);if(ret < 0){//fprintf(stdout, "bind receive socket fail : %s\n", errorn);perror("bind");}char rbuf[1024];while(1){usleep(10000);ret = recvfrom(rsck, rbuf, 5, 0, (struct sockaddr*)&s_addr, &s_len);printf("%d:%s\n", ret,rbuf);}char sbuf[64] = "nice!!";sendto(rsck, sbuf, sizeof(sbuf), 0, (struct sockaddr*)&s_addr, s_len);close(rsck);return 0;}

//发送端源文件#include<stdio.h>#include<stdlib.h>#include<stdbool.h>#include<string.h>#include<sys/socket.h>#include<netinet/in.h>int main(void){int ssck = socket(AF_INET, SOCK_DGRAM, 0);if(ssck < 0){perror("socket");return -1;}struct sockaddr_in dest_addr, src_addr;int dest_len = sizeof(dest_addr);int src_len = sizeof(src_addr);bzero(&dest_addr, sizeof(dest_addr));dest_addr.sin_family = AF_INET;dest_addr.sin_port = htons(5678);dest_addr.sin_addr.s_addr = inet_addr("192.168.188.229");char sbuf[64] = "Hello, i am send";int i=0;char tmp[16];while(1){sprintf(tmp, "[%d]", i++);strncpy(sbuf, "Hello, i am send", 64);strncat(sbuf, tmp, 64);//sleep(1);int slen = sendto(ssck, sbuf, sizeof(sbuf), 0, \(struct sockaddr*)&dest_addr,dest_len);printf("slen = %d , chars : %s\n", slen, sbuf);}recvfrom(ssck, sbuf, sizeof(sbuf), 0, (struct sockaddr*)&src_addr,&src_len);printf("%s\n", sbuf);close(ssck);return 0;}


1 0