您可以使用IP_PKTINFO将数据包被发送到组播组的地址 - 即使套接字认购一堆组播组。完成此操作后,您将按顺序获取数据包并按组地址进行过滤。看下面的例子:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define PORT 1234

#define PPANIC(msg) perror(msg); exit(1);

#define STATS_PATCH 0

int main(int argc, char **argv)

{

fd_set master;

fd_set read_fds;

struct sockaddr_in serveraddr;

int sock;

int opt = 1;

size_t i;

int rc;

char *mcast_groups[] = {

"226.0.0.1",

"226.0.0.2",

NULL

};

#if STATS_PATCH

struct stat stat_buf;

#endif

struct ip_mreq imreq;

FD_ZERO(&master);

FD_ZERO(&read_fds);

rc = sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

if(rc == -1)

{

PPANIC("socket() failed");

}

rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

if(rc == -1)

{

PPANIC("setsockopt(reuse) failed");

}

memset(&serveraddr, 0, sizeof(serveraddr));

serveraddr.sin_family = AF_INET;

serveraddr.sin_port = htons(PORT);

serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);

rc = bind(sock, (struct sockaddr *)&serveraddr, sizeof(serveraddr));

if(rc == -1)

{

PPANIC("bind() failed");

}

rc = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt));

if(rc == -1)

{

PPANIC("setsockopt(IP_PKTINFO) failed");

}

for (i = 0; mcast_groups[i] != NULL; i++)

{

imreq.imr_multiaddr.s_addr = inet_addr(mcast_groups[i]);

imreq.imr_interface.s_addr = INADDR_ANY;

rc = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&imreq, sizeof(struct ip_mreq));

if (rc != 0)

{

PPANIC("joing mcast group failed");

}

}

FD_SET(sock, &master);

while(1)

{

read_fds = master;

rc = select(sock + 1, &read_fds, NULL, NULL, NULL);

if (rc == 0)

{

continue;

}

if(rc == -1)

{

PPANIC("select() failed");

}

if(FD_ISSET(sock, &read_fds))

{

char buf[1024];

int inb;

char ctrl_msg_buf[1024];

struct iovec iov[1];

iov[0].iov_base = buf;

iov[0].iov_len = 1024;

struct msghdr msg_hdr = {

.msg_iov = iov,

.msg_iovlen = 1,

.msg_name = NULL,

.msg_namelen = 0,

.msg_control = ctrl_msg_buf,

.msg_controllen = sizeof(ctrl_msg_buf),

};

struct cmsghdr *ctrl_msg_hdr;

inb = recvmsg(sock, &msg_hdr, 0);

if (inb < 0)

{

PPANIC("recvmsg() failed");

}

for (ctrl_msg_hdr = CMSG_FIRSTHDR(&msg_hdr); ctrl_msg_hdr != NULL; ctrl_msg_hdr = CMSG_NXTHDR(&msg_hdr, ctrl_msg_hdr))

{

if (ctrl_msg_hdr->cmsg_level == IPPROTO_IP && ctrl_msg_hdr->cmsg_type == IP_PKTINFO)

{

struct in_pktinfo *pckt_info = (struct in_pktinfo *)CMSG_DATA(ctrl_msg_hdr);

printf("got data for mcast group: %s\n", inet_ntoa(pckt_info->ipi_addr));

break;

}

}

printf("|");

for (i = 0; i < inb; i++)

printf("%c", isprint(buf[i])?buf[i]:'?');

printf("|\n");

#if STATS_PATCH

rc = fstat(sock, &stat_buf);

if (rc == -1)

{

perror("fstat() failed");

} else {

printf("st_atime: %d\n", stat_buf.st_atime);

printf("st_mtime: %d\n", stat_buf.st_mtime);

printf("st_ctime: %d\n", stat_buf.st_ctime);

}

#endif

}

}

return 0;

}

下面的代码不会解决有机磷农药的问题,但可以指导人们处理类似要求

(EDIT)一个人不应该在深夜做这样的事情。 ..即使采用这种解决方案,您只会得到fd由select处理的订单 - 这将不会提示帧到达的时间。

正如here所述,由于没有为socket inode设置所需的回调,因此目前无法检索套接字的顺序或更改的时间戳。但是如果你能修补你的内核,你可以通过在选择系统调用中设置时间来解决这个问题。

下面的补丁可以给你一个想法:

diff --git a/fs/select.c b/fs/select.c

index 467bb1c..3f2927e 100644

--- a/fs/select.c

+++ b/fs/select.c

@@ -435,6 +435,9 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)

for (i = 0; i < n; ++rinp, ++routp, ++rexp) {

unsigned long in, out, ex, all_bits, bit = 1, mask, j;

unsigned long res_in = 0, res_out = 0, res_ex = 0;

+ struct timeval tv;

+

+ do_gettimeofday(&tv);

in = *inp++; out = *outp++; ex = *exp++;

all_bits = in | out | ex;

@@ -452,6 +455,16 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)

f = fdget(i);

if (f.file) {

const struct file_operations *f_op;

+ struct kstat stat;

+

+ int ret;

+ u8 is_sock = 0;

+

+ ret = vfs_getattr(&f.file->f_path, &stat);

+ if(ret == 0 && S_ISSOCK(stat.mode)) {

+ is_sock = 1;

+ }

+

f_op = f.file->f_op;

mask = DEFAULT_POLLMASK;

if (f_op->poll) {

@@ -464,16 +477,22 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)

res_in |= bit;

retval++;

wait->_qproc = NULL;

+ if(is_sock && f.file->f_inode)

+ f.file->f_inode->i_ctime.tv_sec = tv.tv_sec;

}

if ((mask & POLLOUT_SET) && (out & bit)) {

res_out |= bit;

retval++;

wait->_qproc = NULL;

+ if(is_sock && f.file->f_inode)

+ f.file->f_inode->i_ctime.tv_sec = tv.tv_sec;

}

if ((mask & POLLEX_SET) && (ex & bit)) {

res_ex |= bit;

retval++;

wait->_qproc = NULL;

+ if(is_sock && f.file->f_inode)

+ f.file->f_inode->i_ctime.tv_sec = tv.tv_sec;

}

/* got something, stop busy polling */

if (retval) {

注:

这是......只为你:) - 不要指望它在主线

do_gettimeofday()被称为之前每个相关的fd被测试。 以获得更高的粒度,这应该在每次迭代中完成(并且仅在需要时)。由于stat接口只提供了一秒的粒度,所以你可以(!!很好!)使用剩余的时间属性将秒的小数部分映射到这些字段。

须藤QEMU系统-x86_64的-kernel弓/ 86 /启动/ bzImage的-hda debian_wheezy_amd64_standard.qcow2 - 追加“root =/dev/sda1”

linux获取fifo中的数据数量,Linux select()和多个套接字的FIFO排序?相关推荐

  1. linux 多个select,Linux select()和多个套接字的FIFO排序?

    您可以使用IP_PKTINFO获取数据包发送到的多播组的地址 - 即使套接字订阅了一堆多播组.有了这个,您将按顺序获取数据包并按组地址过滤.请参阅以下示例: #include #include #in ...

  2. SpringBoot之获取配置文件中的数据

    SpringBoot之获取配置文件中的数据 项目结构 配置application.properties book.author=Tom book.name=SpringBoot # spring.pr ...

  3. javascript如何获取request中的数据

    先用jsp获取request中的数据内容,然后将数据存入一个隐藏域中,然后通过javascript获取隐藏域的值

  4. 关于js中获取div中的数据

    原文地址为: 关于js中获取div中的数据 最近用js写了一个计算器的页面.基本上使用到了,ul  li的几点用法.用来布局,并且创造出了很不错的鼠标悬停效果. 关于从中学到的知识: document ...

  5. java筛选表格,java怎么获取excel中的数据_java筛选excel数据

    你好! 请教你个问题 java web程序如何将读取的excel表格里的数据插入到数据库,并显示在JSP页面上? 主要用poi.jar 包.包含两jar就可以了:poi-3.16.jar.poi-oo ...

  6. java 获取自定义参数类型_Springboot中使用自定义参数注解获取 token 中用户数据...

    使用自定义参数注解获取 token 中User数据 使用背景 在springboot项目开发中需要从token中获取用户信息时通常的方式要经历几个步骤 拦截器中截获token TokenUtil工具类 ...

  7. Python字典(字典的定义,创建字典,获取字典中的数据,字典元素增删改,获取字典视图,字典的遍历,字典的特点,字典生成公式)

    1.字典的定义 2.创建字典 3.获取字典中的数据 4.字典元素增删改 5.获取字典视图 lst={'数值1':300,'数值2':100,'数值3':400,'数值4':200} print(lst ...

  8. alin的学习之路(Linux网络编程:一)(网络模型、帧格式、socket套接字、服务器端实现)

    alin的学习之路(Linux网络编程:一)(网络模型.帧格式.socket套接字.服务器端实现) 1. 协议 协议是一组规则,规定了如何发送数据.通信的双发都需要遵守该规则 2. 网络分层结构模型 ...

  9. pandas使用query函数查询dataframe指定数据列的内容(数值)包含在特定列表中的数据行(select rows which column values contain in list)

    pandas使用query函数查询dataframe指定数据列的内容(数值)包含在特定列表中的数据行(select rows which column values contained in a li ...

最新文章

  1. Ubuntu系统执行shell 脚本的方法
  2. 数据解读:资本追逐的14个人工智能细分领域
  3. Visual C++ MFC/ATL开发-高级篇(一)
  4. Jzoj4458 密钥破解——Pollard-rho
  5. 用Tensorflow搭建第一个神经网络
  6. 线性代数 第三章 矩阵的初等变换与线性方程组
  7. 前端“黑话”polyfill
  8. transition的唧唧歪歪
  9. php 向py发起请求,Python向PHP发起GET与POST请求
  10. mysql centos6_Linux下的Mysql的基本操作(CentOS6.6)
  11. 基于java飞机大战游戏
  12. Ubuntu下F2FS文件系统的安装与挂载
  13. 李某同案律师下挑战书
  14. 计算机专业就业前景分析
  15. 魔方机器人需要特制魔方吗_大开眼界:会玩魔方的机器人
  16. Netty框架之Selector使用详解
  17. Ardupilot -- APM源码笔记(重制)~序言
  18. 【指数Lyapunov】Lyapunov指数的MATLAB仿真
  19. linux系统取消报警声,Linux 中警报声的消除
  20. powerpoint无法加载宏mathtype

热门文章

  1. R语言vtreat包自动处理dataframe的缺失值、使用分组的中位数来标准化数据列中每个数据的值(和中位数表连接并基于中位数进行数据标化)、计算数据列的中位数或者均值并进行数据标准化
  2. 如何获取数据库中标的所有字段和数据类型?
  3. R语言生成组合图并保存实战:实际上只保存了最后一个图问题、ggsave生成组合图并保存(保存完整组合图)
  4. R语言dplyr包mutate_if函数修改所有满足条件的数据列的内容实战
  5. pandas为dataframe所有的列名称名添加前缀(add_prefix)
  6. R语言F分布函数F Distribution(df, pf, qf rf )实战
  7. cross-entropy(交叉熵)是什么?用了表征什么东西?
  8. oracle存clob,oracle数据库里保存clob字段-Oracle
  9. Biopython(py012)统计碱基数
  10. 实验五 oracle高级数据查询技术