创建 SOCK_RAW 套接字仅用于发送数据而不使用任何 recvform()

2023-12-31

如果我创建一个类型为 SOCK_RAW 的套接字只是为了发送一些数据而不接收任何数据,那么当内核继续接收网络数据包并将其数据报复制到某个缓冲区(应用程序的?)时,是否会出现任何问题。换句话说,somebuffer被填满后会发生什么?错误或忽略?

我不知道如何阻止内核将数据报的副本传递给我的应用程序。

参考http://sock-raw.org/papers/sock_raw http://sock-raw.org/papers/sock_raw0x4 原始输入

经过IP层处理后 新传入的 IP 数据报,它调用 ip_local_deliver_finish() 内核函数 它负责通过调用注册的传输协议处理程序 检查 IP 标头的协议字段(记住上面的内容)。然而 在将数据报传递给处理程序之前,它每次都会检查是否有 应用程序创建了一个原始套接字same协议号。如果有 是一个或多个这样的应用程序,它会复制数据报并交付 也给他们。


您可以使用关闭(2)为了关闭套接字的接收部分。 看关闭手册页 http://linux.die.net/man/2/shutdown

EDIT :我找到shutdown仅适用于已连接的(即 TCP)套接字。 对于原始套接字,有两种可能性:

  • 将数据接收到临时缓冲区(带有recv)并丢弃它们(也许在另一个线程中)
  • 如果我没记错的话,当套接字缓冲区已满时,传入的数据将被自动丢弃(并且缓冲区中的数据不会被修改),因此您可以将套接字接收缓冲区大小设置为 0(如果需要,稍后可以增加它)。

以下是将接收缓冲区大小设置为 0 的方法:

int opt = 0;
setsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));

TEST

/**
 * @file raw_print_pkt.c
 * @brief 
 * @author Airead Fan <[email protected] /cdn-cgi/l/email-protection>
 * @date 2012/08/22 12:35:22
 */

#include <stdio.h> 
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>

int main(int argc, char *argv[])
{
    int s;
    ssize_t rn;                 /* receive number */
    struct sockaddr_in saddr;
    char packet[4096];
    int count;

    if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) {
        perror("error:");
        exit(EXIT_FAILURE);
    }

    memset(packet, 0, sizeof(packet));
    socklen_t *len = (socklen_t *)sizeof(saddr);
    int fromlen = sizeof(saddr);
    int opt = 0;

    count = 0;
    while(1) {
        if ((rn = recvfrom(s, (char *)&packet, sizeof(packet), 0,
                           (struct sockaddr *)&saddr, &fromlen)) < 0)
            perror("packet receive error:");
        if (rn == 0) {
            printf("the peer has performed an orderly shutdown\n");
            break;
        }

        printf("[%d] rn = %lu \n", count++, rn);

        if (count == 16) {
            if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) {
                perror("setsocketopt failed");
            } else {
                fprintf(stdout, "setsocketopt successful\n");
            }
            // int shutdown(int sockfd, int how);
            /* if (shutdown(s, SHUT_RD) < 0) {
             *     perror("shutdown failed");
             * } */
        }
    }

    return 0;
}

测试2(同样包括):

int main(int argc, char *argv[])
{
int s;
ssize_t rn;                 /* receive number */
char packet[4096];
int count;

if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) {
    perror("error:");
    exit(EXIT_FAILURE);
}

memset(packet, 0, sizeof(packet));
int opt = 0;
count = 0;

//Set recv buffer size
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) {
    perror("setsocketopt failed");
} else {
    fprintf(stdout, "setsocketopt successful\n");
}

//10 seconds countdown
int i = 10;
while(i > 0)
{
    printf("\r%d              ", i);
    fflush(stdout);
    i--;
    sleep(1);
}
printf("\n");
while(1) {
    if ((rn = recv(s, (char *)&packet, sizeof(packet), 0)) <= 0)
        perror("packet receive error:");

    printf("[%d] rn = %lu \n", count++, rn);
    }
return 0;
}

以下是进行测试 2 的方法:

首先,将缓冲区大小设置为 4096(如果网络流量很大,则设置更大)。编译并启动。在开始接收数据之前的10秒内,向套接字发送大量数据。 10 秒后,程序将收到您在倒计时期间发送的所有内容。

之后,将缓冲区大小设置为 0。按照之前的步骤进行。 10秒后,程序将不会收到您在倒计时期间发送的数据。但是如果您在数据存在时发送数据recvfrom,它会正常读取它们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建 SOCK_RAW 套接字仅用于发送数据而不使用任何 recvform() 的相关文章

随机推荐

  • GCP 托管实例组不会扩展到零

    我有一个 GCP 托管实例组 我想使用 cron 计划将其扩展至 0 到 1 个实例 GCP 有一个局限性 https cloud google com compute docs autoscaler scaling schedules l
  • 单击正文,但其他一些标签不起作用

    有谁知道 css 位置 相对 可能会搞乱功能 body not theDIV click function alert 或者问题出在其他地方 发生的情况是 我有一个在单击按钮时出现的图标 并且当我单击主体上除 div 本身之外的任何位置时
  • 为什么我的 Gunicorn Python/Flask 工作人员会退出信号术语?

    我有一个 Python Flask Web 应用程序 我正在通过 Gunicorn 将其部署在 Amazon ECS 上的 Docker 映像中 一切都很顺利 然后突然间 包括最后一次成功的请求 我在日志中看到了这一点 2017 03 29
  • 如何将 ctx(上下文)传递给 CliRunner?

    CliRunner未列出任何参数来在其中提供上下文文档 http click pocoo org 5 api click testing CliRunner invoke 以下内容应作为最低限度的工作示例 真正的问题有点不同 可以通过将单击
  • 使用 EditText 显示密码

    我使用 EditText 输入密码 以及一个用于显示密码或不显示密码的复选框 下面是函数的一部分 public void ShowPassword if cb isChecked password setInputType InputTyp
  • tabBar didSelectItem 似乎不起作用

    在我的头文件中我有这个 interface TabBarController UIViewController
  • PHP 将 XML 转换为 JSON

    我正在尝试在 php 中将 xml 转换为 json 如果我使用简单的 xml 和 json encode 进行简单转换 则 xml 中不会显示任何属性 xml simplexml load file states xml echo jso
  • Angular.json 脚本未加载

    我正在尝试使用bootstrap导航栏的示例来自bootstrap文档 如果我从以下位置加载它angular json切换汉堡不起作用 如果我使用的是来自的 CDN 链接bootstrap docs
  • 要求文件作为字符串

    我正在使用 Node Express 我只是想知道如何将任何文件作为字符串导入 假设我有一个 txt 文件 我想要的只是将其加载到这样的变量中 var string require words txt 我反对 modules exports
  • Android 模拟器 - 创建用户帐户时遇到问题

    我的 Android 模拟器中需要一两个用户帐户 以便我可以测试应用程序的一些短信 邮件功能 问题是 当我尝试在模拟器中执行此操作时 设置 gt 帐户和同步 gt 添加帐户 gt my gmail account password gt 下
  • AngularJS Protractor - 如何测试 AJAX 登录调用?

    我有一个按钮 单击后会在 Angular 中发出 AJAX 调用 promise格式 登录成功后会出现 scope变量被更改并且元素如下所示 section Section to display if logged in section 被
  • 安装 Oracle Database Express Edition 11g 时出现问题

    我正在尝试使用 X ubuntu 13 04 64 位安装 Oracle 数据库本指南 http www techienote com 2012 11 step by step guide to install oracle databas
  • 使用 jdk 1.7 启动 Apache James

    我尝试在 Linux Mint 64 位 Debian 上使用 Java jdk 1 7u17 运行 apache james 3 0 beta4 服务器 但由于 JAXB 库错误而无法工作 根据文档 应下载不同的 jar 文件 http
  • 8086组装师

    我在下面的代码中遇到了这个问题 该代码将数字转换为 ASCII 数字文本 然而 代码似乎在 div 操作码处循环 Main Program main mov ax 0x0000 mov ds ax setup data segment re
  • 使用 JSONPath 进行 Redshift COPY 缺失的数组/字段

    我正在使用 COPY 命令将 JSON 数据集从 S3 加载到 Redshift 表 数据正在部分加载 但它会忽略缺少数据 键值 数组 的记录 即从下面的示例中仅加载第一条记录 Query 从 s3 mybucket address jso
  • 无符号整数的差异 - 获取签名结果的标准支持方法?

    假设两个任意时间戳 uint32 t timestamp1 uint32 t timestamp2 除了转换为更大的有符号类型和相当冗长的 if else 的明显变体之外 是否有标准的一致方法来获得两者的有符号差异 事先不知道哪一个更大 但
  • 研究squashfs压缩比

    是否有任何工具可以检查现有的 squashfs 映像并找出每个文件的压缩率 如果它可以帮助我估计一个巨大的可执行文件中静态链接符号的闪存使用情况 那就加分了 7zip 程序可以提供该信息 使用7z l slt squasfsfile您将获得
  • selenium切换到iframe来定位元素

    selenium import webdriver from selenium webdriver support import expected conditions as EC from selenium webdriver suppo
  • 如何通过 BFS 和 DFS 遍历构建树

    我有BFS and DFS树的遍历 如何从这些遍历中重建树 例如 BFS Traversal 4 3 5 1 2 8 7 6 DFS Traversal 4 3 1 7 2 6 5 8 那么树就会像下面这样 4 3 5 2 1 8 6 7
  • 创建 SOCK_RAW 套接字仅用于发送数据而不使用任何 recvform()

    如果我创建一个类型为 SOCK RAW 的套接字只是为了发送一些数据而不接收任何数据 那么当内核继续接收网络数据包并将其数据报复制到某个缓冲区 应用程序的 时 是否会出现任何问题 换句话说 somebuffer被填满后会发生什么 错误或忽略