基于TCP下MSG_PEEK的套接字接受缓冲区的排队数据量分析
来源:互联网 发布:c51单片机跑马灯程序 编辑:程序博客网 时间:2024/05/29 16:58
如何获取已经排队的数据量:
(1)、获取套接字当中的数据量的目的是为了避免读操作而堵塞在内核中(这样会堵塞整个程序的进行), 为了解决这个问题, 我们可以使用非堵塞IO
(2)、在recv、recvfrom、recvnsg函数当中的flags参数标志,我们可以使用MSG_PEEK标志,仅仅读取该套接字当中缓冲区当中的数据量,但是并不真真的读取该数据,也可以使用MSG_DONTWAIT | MSG_PEEK相结合。但是我们需要注意的是,(针对tcp)可能两次调用recv函数返回的值不同,因为两次调用函数之间可能会数据到来。就针对UDP套接字而言,前一次调用recvfrom函数加上MSG_PEEK标志查看接收对列的数据量,后一次不加该标志调用recvfrom函数读取数据,那么两次的返回值(数据报大小、内容、发报者地址)将会是完全相同。
(3)、一些支持ioctl的FIONREAD命令。改命令第三个值-结果参数也会指向某个整数的一个指针,内核通过该整数返回的值就是套接字接收对列里面当前所有数据的字节数;而对于UDP而言,就是所有的已排队数据报的总和的字节数大小。因为针对UDP中返回值包括Ip地址和端口号(IPv4是16字节,IPv6是24字节)。
TCP连接的条件下 代码如下
客户端核心代码片段如下:
#include "unp.h"void str_cli(FILE *fp, int sockfd){ int maxfdp, stdineof = 0; char sendbuf[MAXLINE], recvbuf[MAXLINE]; fd_set rset; FD_ZERO(&rset); int num; for(;;){ if(stdineof == 0) FD_SET(fileno(fp), &rset); FD_SET(sockfd, &rset); maxfdp = fileno(fp); if((num = Select(maxfdp + 1, &rset, NULL, NULL, NULL)) < 0){ if(errno == EINTR) { fprintf(stdout, "semaphore lead to system call\n"); continue; }else{ fprintf(stdout, "select error\n"); } } if(FD_ISSET(sockfd, &rset)){ if(Readline(sockfd, recvbuf, MAXLINE) <= 0){ if(stdineof == 1){ return; } if(errno == EINTR){ fprintf(stdout, "system call interrupted\n"); continue; }else{ fprintf(stdout, "read error\n"); } } fprintf(stdout, "read error\n"); Fputs(recvbuf, stdout); } if(FD_ISSET(fileno(fp), &rset)){ if(Fgets(sendbuf, MAXLINE, fp) == NULL){ FD_CLR(fileno(fp), &rset); Shutdown(sockfd, SHUT_WR); stdineof = 1; continue; } Writen(sockfd, sendbuf, strlen(sendbuf)); } }}代码分析:我相信自己看得懂
tcp服务器端核心代码如下
#include "unp.h"void _str_echo(int sockfd){ char recvbuf[MAXLINE]; int n; for(;;){ n = Recv(sockfd, recvbuf, MAXLINE, MSG_PEEK); if(0 == n) break; //server close connect else{ int npend; sleep(1); Ioctl(sockfd, FIONREAD, &npend); fprintf(stdout, "%d bytes from PEEK, %d bytes pending\n", n,npend); n = Read(sockfd, recvbuf, MAXLINE); recvbuf[n] = 0; Fputs(recvbuf, stdout); } }}代码分析:
1、MSG_PEEK会把数据读到缓冲区,但是并不会清理套接字中的数据,还可以供其他进程读取。
2、ioctl的FIONREAD也可以读取套接字中缓冲区的数据。
运行结果如下:
阅读全文
0 0
- 基于TCP下MSG_PEEK的套接字接受缓冲区的排队数据量分析
- 《网络编程》基于 TCP 套接字编程的分析
- LINUX 下tcp 和 udp 套接字收发缓冲区的大小决定规则
- LINUX 下tcp 和 udp 套接字收发缓冲区的大小决定规则 .
- Linux下tcp 和 udp 套接字收发缓冲区的大小决定规则
- Linux下tcp 和 udp 套接字收发缓冲区的大小决定规则
- LINUX 下tcp 和 udp 套接字收发缓冲区的大小决定规则
- Linux下tcp 和 udp 套接字收发缓冲区的大小决定规则
- TCP/UDP 套接字及缓冲区的一些问题
- 基于TCP通信的套接字Socket
- 套接字缓冲区的大小
- TCP下的套接字编程
- Linux下套接字详解(六)----基于pthread的多线程的TCP套接字(阻塞/同步/并发)
- LINUX 下tcp 和 udp 套接字收发缓冲区问题
- LINUX 下tcp 和 udp 套接字收发缓冲区问题
- Linux下套接字详解(五)----基于fork多进程的TCP套接字(阻塞/同步/并发)
- TCP的套接字
- 基于TCP套接字实现简单的通信
- 安装Elasticsearch 5.5.0 (Windows)
- HDU2376Average distance(树形dp|树上任意两点距离和的平均值)
- Linux下安装JDK 和TOMCAT
- PHP中单引号与双引号的区别
- String[]数组,ArrayList 和 LinkedList的区别
- 基于TCP下MSG_PEEK的套接字接受缓冲区的排队数据量分析
- Logstash学习总结(二) INPUT应用实例2
- windows下eclipse开发hadoop的坑
- Java高级之HashMap那些事
- oracle控制语句学习
- iOS 点击UITableViewCell上的控件获取对应的cell
- C# 如何正确删除List中的item
- Activiti工作流学习(一)
- VS2010中调试DLL工程的方法