博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据报截断
阅读量:6424 次
发布时间:2019-06-23

本文共 2657 字,大约阅读时间需要 8 分钟。

当一个到达UDP当数据包超过由应用程序提供的缓冲容量,recvmsg在其 msghdr结构体msg_flags设置成员MSG_TRUNC马克。
全面支持msghdr结构msg_flags提供会员达到这样的通知。

但并不是全部实现都以同一种方式处理超过预期长度的UDP数据报

存在三种情况:
1.丢弃超出部分的字节并向应用进程返回MSG_TRUNC标志,调用recvmsg能够接收这个标志
2.丢弃超出部分的字节但不通知这个标志

3.保留超出部分的字节并在同一套接字兴许的读操作中返回它们

实例

客户程序

#include 
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;struct buf{ int order; unsigned char data[10]; int add;};int main(){ int sockfd; int r; int on = 1; struct sockaddr_in saddr; struct buf buf; sockfd = socket(AF_INET, SOCK_DGRAM, 0); setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); bzero(&saddr, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = inet_addr("192.168.199.255"); saddr.sin_port = htons(9999); buf.order = 1; strcpy((char*)buf.data, "Hello"); buf.add = 2; r = sendto(sockfd, &buf, sizeof(buf), 0, (struct sockaddr*)&saddr, sizeof(saddr)); if (r == -1) { perror("sendto error"); exit(-1); } cout << "finish" << endl; return 0;}

服务程序

#include 
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;struct buf{ int order; unsigned char data[10];};int main(){ int sockfd; int r; socklen_t len; struct sockaddr_in saddr; struct buf buf; struct sockaddr_in caddr; struct msghdr msg; struct iovec iov; struct cmsghdr *cmptr; union { struct cmsghdr cm; char control[CMSG_SPACE(sizeof(int))]; } control_un; sockfd = socket(AF_INET, SOCK_DGRAM, 0); bzero(&saddr, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(9999); if (bind(sockfd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0) { perror("bind error"); exit(-1); } msg.msg_name = NULL; msg.msg_namelen = 0; iov.iov_base = &buf; iov.iov_len = sizeof(buf); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = control_un.control; msg.msg_controllen = sizeof(control_un.control); msg.msg_flags = 0; while (1) { r = recvmsg(sockfd, &msg, 0); if (r < 0) { perror("recvfrom error"); exit(-1); } cout << buf.order << endl; cout << buf.data << endl; cout << endl; int recv_len = r; //推断是否发生数据报截断 if (msg.msg_flags == MSG_TRUNC) { cout << "数据报截断" << endl; unsigned char temp_buf[200]; r = recvfrom(sockfd, &temp_buf, sizeof(temp_buf), 0, NULL, 0); if (r == recv_len+sizeof(int)) { cout << "超出的部分被保留" << endl; } else { cout << "超出的部分被丢弃" << endl; } } } return 0;}
运行结果:

发送第一个数据报

发送第二个数据报

发送第三个数据报

版权声明:本文博客原创文章。博客,未经同意,不得转载。

你可能感兴趣的文章
系统批量安装
查看>>
android完美解决动态创建spinner点击,错误
查看>>
ASP.NET aspx页面中 写C#脚本; ASP.NET 指令(<%@%>);
查看>>
iOS崩溃日志分析-b
查看>>
更数数据库用户密码
查看>>
jQuery学习笔记
查看>>
ps命令查出来的rss/vsz/size分别是何含义呢
查看>>
【转】js弹出框详解
查看>>
The Big List of What’s New or Improved in Silverlight 5
查看>>
Silverlight开发廋身攻略(一)
查看>>
使用VMware Workstation搭建基于Linux的Oracle 10g RAC
查看>>
Sharepoint学习笔记—Debug&TroubleShooting--工具清单
查看>>
Jenkins FQA
查看>>
ORACLE学习笔记--性能优化4
查看>>
百度之星 / 初赛第二场 B题
查看>>
WSUS完全部署
查看>>
java foreach循环为什么不能赋值
查看>>
AD用户登录验证,遍历OU(LDAP)
查看>>
Configuration
查看>>
ContextLoaderListener作用详解
查看>>