8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

为什么我在尝试使用 Amazon Connect Streams 时收到 frame-ancestor 错误

here_for_help 3月前

173 0

错误:页面的设置阻止了资源(frame-ancestors)的加载,因为它违反了以下指令:“frame-ancestors 'self'”背景:当我尝试加载页面时

错误:

该页面的设置阻止了资源(frame-ancestors)的加载,因为它违反了以下指令:“frame-ancestors 'self'”

背景:

当我尝试使用此脚本加载页面时:

var containerDiv = document.getElementById("container-div"); 
var instanceURL = "[Their Instance].my.connect.aws/ccp-v2"; 
// initialize the streams api 
function init() 
{ // initialize the ccp 
    connect.core.initCCP(containerDiv, { 
        ccpUrl: instanceURL,
        loginUrl: '[Their Instance Login URL]', 
        softphone: 
        {
            allowFramedSoftphone: true, 
        } 
    }); 
}

iframe 无法加载并提供我提供的初始错误。我需要指示他们做些什么才能允许嵌入超出我们网站接受来源的范围?AWS 接受的来源是否也允许本地主机(用于测试)?我正在我的机器上本地进行开发。

我正在尝试使用 amazon connect streams JS 将第三方客户端的 amazon connect 嵌入到我们的网站(他们正在与我们合作来完成这项工作,并已将我们的网站添加到他们接受的来源中)。

我还检查了 IIS(我们用它来托管我们的应用程序)并修改了我们用来允许在我们这边嵌入的 HTTP 标头。

信息:

我们的应用程序使用 C# 和 ASP.NET,嵌入的页面是标准的 aspx 页面。

他们提供了实例,我可以直接与第三方客户合作。

帖子版权声明 1、本帖标题:为什么我在尝试使用 Amazon Connect Streams 时收到 frame-ancestor 错误
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由here_for_help在本站《asp.net》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 我遇到这样一种情况,使用多接口,我有一组正在运行的传输,在某些时候我想停止其中一个,即使我不确定传输是否已经完成......

    我遇到过这样一种情况,在使用多接口时,我有一组正在运行的传输,在某个时候我想停止其中一个,即使我不确定传输是否已经完成(例如,我现在不关心该特定传输是否完成)。我想知道当传输 curl_multi_info_read 停止时消息队列(您用 查询的那个)究竟发生了什么,或者如果我在删除 easy 处理程序之后但在检查消息之前删除它,会发生什么。

    想象一下以下情况:

    CURL* h = curl_easy_init();
    curl_easy_setopt(blablabla);
    // more setopts, url, etc
    
    curl_multi_add_handle(my_curlm, h);
    
    int running_transfers;
    curl_multi_perform(my_curlm, &running_transfers);
    
    // At some point in the future:
    curl_multi_remove_handle(my_curlm, h);
    

    我目前有两点疑惑:

    • 如果传输尚未完成,消息队列是否会填充一条新消息,指示该处理程序已完成?如果是这种情况,是否有任何结果代码可供我检查,以了解传输是否因明确停止而结束? 注意: 其中一个 CURL 错误代码是 CURLE_ABORTED_BY_CALLBACK ,但我不知道通过从多处理程序中移除来停止传输是否包含在该错误代码中。
    • 如果传输已经完成并且队列中有新消息,或者传输尚未完成但停止它在队列中插入了新消息(上述情况),然后我用删除简单处理程序, curl_easy_cleanup 消息会从队列中消失吗?还是我需要保持简单处理程序处于活动状态,直到我检查完队列中的所有消息?

    我在这里喜欢的语义是,无论传输是否完成,或者队列中是否有引用它的待处理消息,如果我使用 curl_easy_cleanup (从多处理程序中删除它之后)删除简单处理程序,则引用该简单处理程序的任何消息都会消失。

  • 我正在寻求在 JavaScript + WebAssembly 中实现 RandomX 工作量证明哈希函数。README 解释了这是不可能的:由于需要大量内存,因此 Web 挖掘不可行...

    我希望在 JavaScript + WebAssembly 中实现 RandomX 工作量证明哈希函数。README 解释了为什么这是不可能的:

    由于内存需求大,且 Javascript 和 WebAssembly 中缺乏对浮点运算的定向舍入支持,因此 Web 挖掘不可行。

    由于广泛使用 CFROUND 在字节码中使用指令重复切换舍入模式,并且 JavaScript 无法更改舍入模式,甚至无法使用除偶数舍入之外的任何其他舍入模式,因此这是不可能的。

    CFROUND 指令操作 fprc RandomX 规范内的抽象寄存器。 fprc 从零开始,因此回合与偶数相关,并且在每次指令执行时似乎随机更新。

    fprc 舍入模式
    0 roundTiesToEven
    1 朝负方向舍入
    2 roundTowardPositive
    3 朝零方向舍去

    RandomX 使用 5 个正确舍入的运算,add、sub、mul、div 和 sqrt 保证按照 IEEE754 规范以双精度正确舍入。我的问题是这样的。 软浮点不是一种选择,我只能在舍入到偶数的情况下访问这 5 个运算的浮点算法。我需要找到一种方法来模拟双精度算法,所有其他舍入模式都以这 5 个运算的一种舍入模式实现。这比软浮点快得多。

    Bruce 在 Random ASCII 博客 发表了一些言论:

    如果我理解正确,那么其他三种舍入模式将产生与舍入到最近偶数相同或相差一个 ULP 的结果。如果舍入到最近偶数操作是精确的,那么所有舍入模式都会产生相同的结果。如果不精确,那么您必须弄清楚哪些结果会有所不同。我认为向负舍入或向正舍入将相差一个 ULP,但不会同时相差两个。

    FMA(融合乘加)运算在 JavaScript 中不可用,但它们在 WebAssembly 中可用,但受 非确定性运算 (未得到广泛支持)的约束。这些运算是 f32x4.relaxed_*madd f64x2.relaxed_*madd 。如果需要使用 FMA,这没问题,我可以实现回退。

    唯一一篇稍微接近浮点舍入模式模拟的论文是 《使用舍入到最近偶数位的算法模拟舍入到最近零位的“增强”浮点运算》 。它提出了一些有趣的观点,但没有用。

    附加信息 0: RandomX 使用两类抽象浮点寄存器进行运算,即组 F(加法运算)和组 E(乘法运算)。根据规范,F 的绝对值永远不会超过 3.0e+14 ,组 E 的近似范围是 1.7E-77 infinity 始终为正)。浮点运算的所有结果都 绝不能 是 NaN。答案可能会考虑到这一点。

    附加信息 1 (地址 @sech1 注释): FSCAL_R 指令使事情变得复杂。有效执行该指令需要操作实际的浮点二进制格式:

    上述数学运算相当于对二进制表示与以下值进行按位异或: 0x80F0000000000000 .

    这意味着其他形式的表示(双精度、定点)已经不复存在:

    由于 F 组寄存器的有限范围允许使用更有效的定点表示(80 位数字),因此 FSCAL 指令会操纵浮点格式的二进制表示,从而使这种优化更加困难。

    指令可以在两个双精度数之间展开, FSCAL_R 那么双精度算术就有可能起作用

    附加信息2(地址@aka.nice @sech1):

    所有浮点运算均根据 fprc 寄存器的当前值进行舍入(见表 4.3.1)。由于浮点寄存器值的限制,任何运算都不会产生 NaN 或非规格化数。

    我已开始执行计算,将所有输出数字限制在其范围内,以便在 E 组和 F 寄存器上执行操作(没有非正规数、没有 NaN 等),结果答案会偏离一位或导致无穷大。

    我采纳了@aka.nice关于使用双产品实施操作的建议。 测试工具和失败/成功输出在这里 。摘录如下:

    FAIL: [mul(FE_UPWARD)] truth(...) == 0x1.00c915254a87ep+968 != op(...) == 0x1.00c915254a87dp+968
    mul(FE_UPWARD): 19/20
    FAIL: [mul(FE_DOWNWARD)] truth(...) == 0x1.fffffffffffffp+1023 != op(...) == inf
    FAIL: [mul(FE_DOWNWARD)] truth(...) == 0x1.00c915254a87dp+968 != op(...) == 0x1.00c915254a87cp+968
    FAIL: [mul(FE_DOWNWARD)] truth(...) == 0x1.fffffffffffffp+1023 != op(...) == inf
    FAIL: [mul(FE_DOWNWARD)] truth(...) == 0x1.fffffffffffffp+1023 != op(...) == inf
    FAIL: [mul(FE_DOWNWARD)] truth(...) == 0x1.fffffffffffffp+1023 != op(...) == inf
    FAIL: [mul(FE_DOWNWARD)] truth(...) == 0x1.fffffffffffffp+1023 != op(...) == inf
    mul(FE_DOWNWARD): 14/20
    FAIL: [div(FE_TOWARDZERO)] truth(...) == 0x1.71bb8430246b4p-58 != op(...) == 0x1.71bb8430246b3p-58
    FAIL: [div(FE_TOWARDZERO)] truth(...) == 0x1.c254556a24a56p+73 != op(...) == 0x1.c254556a24a55p+73
    FAIL: [div(FE_TOWARDZERO)] truth(...) == 0x1.a67a7c9cb8d59p+483 != op(...) == 0x1.a67a7c9cb8d58p+483
    

    附加信息3(地址@aka.nice):

    我已经取得了很大的进步,目前已经实现了加法和减法、98%的乘法和40%的除法和平方根。

    我已经调整了 round_toward 函数,使其按照 OpenCL 中实现的 RandomX VM .

    double round_toward(double c, double res, int fe) {
        if (isinf(c)) {
            // fe & 1
            uint64_t inf_rnd = (2047UL << 52) - (fe == FE_DOWNWARD || fe == FE_TOWARDZERO);
            return u64_double(inf_rnd);
        }
        ...
    

    未实施FMA的双产品实施进度落后1%:

    void split64(double x, int delta, double *x_h, double *x_l) {
        // https://github.com/dsiem/ErrorFreeTransforms.jl/blob/master/src/mul.jl
    
        double f = (1UL << delta) + 1;
        double c = x * f;
        double h = c - (c - x);
        double l = x - h;
    
        *x_h = h;
        *x_l = l;
    }
    
    // 100% success
    double mul_residue(double a, double b, double c) {
        return fma(a, b, -c);
    }
    
    // 99% success
    double mul_residue(double a, double b, double c) {
        double a_h, a_l;
        double b_h, b_l;
    
        split64(a, 27, &a_h, &a_l);
        split64(b, 27, &b_h, &b_l);
    
        return a_l * b_l - (((c - a_h * b_h) - a_l * b_h) - a_h * b_l);
    }
    

    代码输出与双产品 EFT 相同,与 FMA 的使用不匹配:

    FAIL: [mul(FE_TOWARDZERO)] truth(0x1.3459aa1f9d423p-244, 0x1.47ebd8e19bd97p+1017) == 0x1.8afa9bd8f2f64p+773 != op(...) == 0x1.8afa9bd8f2f65p+773
    FAIL: [mul(FE_TOWARDZERO)] truth(0x1.36a0e20b199b7p+997, 0x1.441f01389c628p-96) == 0x1.89493d0cbd95dp+901 != op(...) == 0x1.89493d0cbd95ep+901
    mul(FE_TOWARDZERO): 498/500
    FAIL: [mul(FE_UPWARD)] truth(0x1.4c46f791b3cb9p+1001, 0x1.a55d5da424cd1p-165) == 0x1.1174f23ab0e37p+837 != op(...) == 0x1.1174f23ab0e36p+837
    FAIL: [mul(FE_UPWARD)] truth(0x1.8c3c4851d9b75p-162, 0x1.ae85675639db9p+1006) == 0x1.4d2dde5e628f5p+845 != op(...) == 0x1.4d2dde5e628f4p+845
    mul(FE_UPWARD): 498/500
    FAIL: [mul(FE_DOWNWARD)] truth(0x1.3459aa1f9d423p-244, 0x1.47ebd8e19bd97p+1017) == 0x1.8afa9bd8f2f64p+773 != op(...) == 0x1.8afa9bd8f2f65p+773
    FAIL: [mul(FE_DOWNWARD)] truth(0x1.36a0e20b199b7p+997, 0x1.441f01389c628p-96) == 0x1.89493d0cbd95dp+901 != op(...) == 0x1.89493d0cbd95ep+901
    mul(FE_DOWNWARD): 498/500
    

    当前实现在这里。我已经非常接近了,只是一些极端情况和除法和平方根的实现。最好让函数 mul_residue 在有或没有的情况下完全相同, fma() 这样优化就不会改变输出。

    附加信息4(地址@aka.nice):

    当前实现附有实现的通过率和边缘情况)通过了所有测试,每个操作和舍入模式均取 50 万个浮点数样本,但仅在 mul_residue 使用 实现 fma() split() 的代码 mul_residue() 如下所示:

    void split64(double a, double *x_h, double *x_l) {
        double f = (1UL << 26) + 1;
        double c = f * a;
        double x = c - (c - a);
        double y = a - x;
    
        *x_h = x;
        *x_l = y;
    }
    
    double mul_residue(double a, double b, double c) {
        // 100% pass rate
        //return fma(a, b, -c);
    
        // 90% pass rate
        double a1, a2;
        double b1, b2;
    
        split64(a, &a1, &a2);
        split64(b, &b1, &b2);
    
        double r1 = a * b - (a1 * b1);
        double r2 = r1 - (a1 * b2);
        double r3 = r2 - (a2 * b1);
        double res1 = a2 * b2 - r3;
        double res2 = a * b - c;
    
        return res1 + res2;
    }
    
  • 我认为双字算术可能是一个可行的选择。

    a b 为正非零浮点数。考虑无误差变换, a+b -> x,y 其中 x = RN(a+b) y = (a+b)-x 。( x y 可以通过众所周知的 2Sum 算法计算。) 1 假设没有发生下溢/上溢。然后,如果 y = 0 ,总和是精确的,并且所有舍入模式都会对给出相同的结果 a+b 。如果 y > 0 ,则向上舍入,远离零或向正无穷舍入, nextafter(x,+INFINITY) 。相反,如果 y<0 ,向下舍入,向零或负无穷舍入,结果为 nextafter(x,-INFINITY) .

    我认为这个具体的例子可以推广到其他运算(例如乘法)和所有浮点值。正如前面所说,有很多情况需要考虑。边缘情况无疑会特别乏味。

    一个很好的参考文献:Jean-Michel Muller,Laurence Rideau。 双字算术的形式化,以及对“双字算术基本构建块的严格和严格的错误界限”的评论 。ACM 数学软件交易,计算机协会,2022,48(1),第 1-24 页。10.1145/3484514。hal-02972245v2。 链接

  • PAA 3月前 0 只看Ta
    引用 5

    是的,二和二乘算法。注意,x+/-ulp(x) 可能在除二元边界之外的任何地方都有效。最好模拟标准的 nextafter 函数

  • 您无法完全不使用软浮点,但您需要的唯一软浮点操作是 FMA: https://github.com/SChernykh/RandomX_OpenCL/blob/master/RandomX_OpenCL/CL/randomx_vm.cl#L1406 检查 \'fma_soft\'、\'div_rnd\'、\'sqrt_rnd\' 函数。

    编辑:但我认为更好的方法是使用 2 个浮点变量来使精度加倍: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#Double-double_arithmetic

    https://www.youtube.com/watch?v=6OuqnaHHUG8

    这样,您将有足够的位来确定在每种舍入模式下应采用哪种舍入方式。但要准备好为所有极端情况编写大量“if” - 上面的“fma_soft”代码非常庞大,这是有原因的。

  • 我已更新问题,提到了 double-double 算术,以及它可能不起作用的原因。我很感激这个答案。

  • 在我看来,我们不需要 FMA 的全部复杂性,因为在计算残差舍入误差时,我们总是处于一个特殊情况,即最高有效部分将被取消。因此,双产品算法就足够了。

  • 在实现四舍五入 FMA 时,您只需对中间操作使用 double-double,所有 FP 操作的所有输入和输出都可以存储为标准 IEEE754 double 值。所以这不是问题。此外,RandomX 没有非正规数,因此您不必担心它们(回答此处的另一条评论)。

  • 引用 10

    如果没有 FMA,您可以使用双产品算法

    只要指数不溢出或下溢,两个积就会产生精确的乘法,形式为两个浮点数的和:

    a x b = round(a x b) + residue
    

    如果余数为正,则应向上舍入,那么正确答案是 round(axb) 之后朝正无穷方向的下一个浮点数。

    对于除法,我们也可以通过乘法得到余数:

    round(a/b) x b = round( round(a/b) x b) + residue_1
    

    我们寻找的残留物有点不同:

    (a/b) x b = round(a/b) x b + residue
    

    因此,感兴趣的残基为:

    residue = a - round(a/b) x b
    residue = (a - round( round(a/b) x b)) - residue_1
    

    类似地,对于 sqrt:

    round(sqrt(a)) x round(sqrt(a)) = round(round(sqrt(a)) x round(sqrt(a))) + residue_1
    
    a = round(sqrt(a)) x round(sqrt(a)) + residue
    
    residue = (a - round(round(sqrt(a)) x round(sqrt(a)))) - residue_1
    

    由于我们感兴趣的是余数的符号而不是真值,因此我们可以对操作数应用 2^n 比例,以避免上溢/下溢情况

    这是使用二和二积来查找残差舍入误差的解决方案的草图。

    该解决方案需要使用标准 nextafter() 函数的某些实现,可以从多个地方找到,例如 https://github.com/scijs/nextafter/blob/master/README.md

    请原谅我的 javascript 技能可能非常近似,但您会明白的。

    const TO_NEAREST = 0;
    const TO_NEGATIVE_INFINITY: = 1;
    const TO_POSITIVE_INFINITY: = 2;
    const TO_ZERO: = 3;
    const ROUNDING_DIRECTION=[Number.NaN , Number.Number.NEGATIVE_INFINITY , Number.POSITIVE_INFINITY , 0.0];
    
    function split(a)
    // helper function for two product, split a number intwo parts a=x+y
    // each part having no more than 26 consecutive bits set
    {
        let splitter=1+Math.pow(2,26); // splitter of two-product algorithm for double precision
        let c = factor*a; // BEWARE: might overflow for big a, but this case has been excluded a priori
        let x = c - (c-a);
        let y = a - x;
        return [x,y];
    }
    
    function mul_residue(a,b,c)
    // answer the residue of exact operation a*b-c
    // using the two product algorithm
    // could be expressed as fma(a,b,-c)
    // limitations: might fail if operations overflow/underflow
    {
        let [a1,a2] = split(a);
        let [b1,b2] = split(b);
        let r1 = a*b - (a1*b1);
        let r2 = r1 - (a1*b2);
        let r3 = r2 - (a2*b1);
        let res1 = a2*b2 - r3;
        let res2 = a*b - c;
        return res1 + res2;
    }
    
    function mul_residue_scaled(a,b,c)
    // answer the residue of exact operation a*b-c
    // after applying some scaling to avoid overflow/underflow
    {
        let [a_scaled , expa] = frexp(a);
        let [b_scaled , expb] = frexp(b);
        let c_scaled = ldexp(c , -expa-expb );
        return mul_residue(a_scaled,b_scaled,c_scaled)
    }
    
    function sum_residue(a,b,c)
    // answer the residue of operation c=a+b using the two sum algorithm
    {
        let a1=c-b;
        let b1=c-a;
        let delta_a=a-a1;
        let delta_b=b-b1;
        let res=delta_a+delta_b;
        return res;
    }
    
    function round_toward(c,res,mode)
    // round the result c to upper or lower, depending on the residue and rounding mode
    {
        let direction=ROUNDING_DIRECTION[ mode ];
        if(res > 0.0 && c < direction) return nextafter(c,direction);
        if(res < 0.0 && c > direction) return nextafter(c,direction);
        return c;
    }
    
    function round_sum(a,b,mode)
    {
        let c=a+b;
        // directed rounding might avoid case of overflow
        if ( (! isFinite(c)) && isFinite(a) && isFinite(b) && (b != 0)) return round_toward(c,-c,mode);
        res=sum_residue(a,b,c);
        return round_toward(c,res,mode);
    }
    
    function round_sub(a,b,mode)
    {
        return round_sum(a,-b,mode);
    }
    
    function round_mul(a,b,mode)
    {
        let c=a*b;
        if ( (! isFinite(c)) && isFinite(a) && isFinite(b) && (b != 0)) return round_toward(c,-c,mode);
        let res=mul_residue_scaled(a,b,c);
        return round_toward(c,res,mode);
    }
    
    function round_div(a,b,mode)
    {
        let c=a/b;
        if ( (! isFinite(c)) && isFinite(a) && isFinite(b) && (b != 0)) return round_toward(c,-c,mode);
        let res= mul_residue_scaled(c,b,a);
        return round_toward(c,-res * Math.sign(b),mode);
    }
    
    function round_sqrt(a,mode)
    {
        let c=Math.sqrt(a);
        let res=mul_residue_scaled(c,c,a);
        return round_toward(c,-res,mode);
    }
    

    这是模拟 frexp 和 ldexp 的候选实现。
    请注意,乘以 2 的幂是一个精确运算,除非结果下溢,此 ldexp 模拟会处理这种情况。

    function exponent_bits(x)
    // extract the 11 bits of float representation encoding the exponent part
    {
        let float = new Float64Array(1),
        let bytes = new Uint8Array(float.buffer);
        float[0] = x;
        return ((bytes[7] & 0x7f) << 4 | bytes[6] >> 4);
    }
    
    function exponent(x)
    // answer the exponent of x
    // where non zero finite x can be represented as
    //    sign * significand * 2^exponent
    // with significand in the interval (0.5,1(
    // undefined behaviour for special values infinity and NaN
    {
        if(x === 0) return 0;
        let e = exponent_bits(x);
        if(e === 0) return exponent( x*Math.pow(2.0,53) ) - 53;
        return e - 1022;
    }
    
    function frexp(x)
    // emulate stdlib frexp function
    // answer the number scaled by a power of two so that it's magnitude fall in interval (0.5,1(
    // and the associated power
    {
        if( ! isFinite(x)) return [x,0];
        if( x == 0 ) return [x,0];
        let e = exponent(x);
        return [ldexp(x,-e) , e];
    }
    
    function ldexp(x,n)
    // emulate stdlib ldexp function
    // scale a number by a power of two : x * 2^n
    {
        if( ! isFinite(x)) return x;
        if( x == 0 ) return x;
        if( n > 1023 ) return ldexp(ldexp(x,1023),n-1023);
        if( n >= -1074) return x * Math.pow(2.0,n);
        // care to avoid inexact result in case of underflow
        let delta_to_underflow = Math.max( exponent(x) - 1022 , -1074 );
        // handle case of total cancellation
        if (delta_to_underflow >= 0) return ldexp(ldexp(x,-1022),n+1022);
        ldexp(ldexp(x,delta_to_underflow),n-delta_to_underflow);
    }
    
  • 我计划使用特征检测来正确舍入 fma(),并按照您的建议,尽可能用 fma(a,b,-c) 替换 mul_residue()。我还不能将此答案标记为已接受,因为我必须继续实施,但这正是我所需要的。

  • 注意,`case TO_ZERO:`应该简化为nextafter(c,0.0)。

  • Meep 3月前 0 只看Ta
    引用 13

    哦,代码不适用于舍入非规范化结果,因为没有办法表示残差小于最小非规范化浮点数... 在计算残差之前应该应用一些缩放(如果我们想要防止潜在的溢出/下溢,我们可以缩放 a 和 b 以获得零指数,并在调用 mul_residue 之前对 c 应用缩放)。 FMA 也是如此...

  • 我已经做了这些调整,您可以在此处看到输出。结果非常接近,我很快将不得不再次更新帖子,以提及许多这些新细节。这个 PDF 非常有助于我理解许多这些 FP 概念。您说得对,它在非正规数上失败了。对于 mul(FE_DOWNWARD) -0x0.00000000000001p-1022 != op(...) == -0x0p+0 或 0x1.ffffffffffffffp+1023 != op(...) == inf

  • 好的,测试工具超出了上溢/下溢/非有限浮点的限制...我尝试在编辑中处理缩放。只需将对 mul_residue 的调用替换为 mul_residue_scaled...

  • 我打开一个 TCP 套接字并将其连接到网络上其他位置的另一个套接字。然后我可以成功发送和接收数据。我有一个计时器,每秒都会向套接字发送一些内容。我...

    我打开一个 TCP 套接字并将其连接到网络上其他位置的另一个套接字。然后我可以成功发送和接收数据。我有一个计时器,每秒向套接字发送一些内容。

    然后我粗鲁地强行断开连接(在这种情况下拔出以太网电缆)。我的套接字仍然报告每秒都在成功写入数据。这种情况持续了大约 1 小时 30 分钟,最终出现写入错误。

    套接字最终接受另一端的超时消失的原因是什么?是操作系统 (Ubuntu 11.04),还是来自 TCP/IP 规范,还是套接字配置选项?

  • 拔掉网线不会中断 TCP 连接 (1),但会中断通信。您可以重新插入网线,一旦建立 IP 连接,所有后台数据都会移动。这就是 TCP 即使在蜂窝网络上也可靠的原因。

    TCP 发送数据时,会等待 ACK 回复。如果在一定时间内未收到任何回复,则会重新传输数据并再次等待。传输间隔的等待时间通常会呈指数增长。

    经过一定次数的重传或总时间没有收到 ACK 后,TCP 将认为连接已“中断”。重传次数或时间长短取决于您的操作系统及其配置,但通常会超时几分钟。

    来自 Linux 的 tcp.7 手册页 :

       tcp_retries2 (integer; default: 15; since Linux 2.2)
              The maximum number of times a TCP packet is retransmitted in
              established state before giving up.  The default value is 15, which
              corresponds to a duration of approximately between 13 to 30 minutes,
              depending on the retransmission timeout.  The RFC 1122 specified
              minimum limit of 100 seconds is typically deemed too short.
    

    这很可能是您想要调整的值,以改变检测连接是否消失所需的时间。

    (1) 也有例外。操作系统在注意到电缆被拔出后,可以通知上层所有连接都应视为“断开”。

  • 我每天都会发出数千个 Http 请求,现在我正在使用 Websockets(nodejs),所以很自然地我想更多地了解老式的套接字,现在我意识到套接字的工作方式是多么优美。可靠的、面向连接的和特定于主机的协议,因为这就是为什么重试次数取决于操作系统!

  • 引用 19

    您还可以提及接收/发送缓冲区大小的填充率吗?如果发送缓冲区已填满,应用程序可能会收到 i/o 错误。

  • 应用程序不会收到 I/O 错误。一旦接收方的“接收窗口”为空,接收方将阻止或读取零字节,具体取决于读取是同步还是异步。一旦发送方的“发送窗口”(以及任何其他操作系统缓冲区)已满,发送方将阻止或发送零字节,这也取决于情况。直到 TCP 确定连接“断开”时,才会发生 I/O 错误。

返回
作者最近主题: