2016-07-21 5 views
1

アプリケーションレベルのaccept edソケットをperlまたはCのIO :: Socket :: INETでリセットするには?アプリケーションからTCPソケット接続をリセットする

プログラムの開発bind ING、それread sおよびwriteのいくつかのデータその後listenは、クライアント接続をTCPポートにする、とaccept sがあります。 ソケットがcloseまたはshutdownの場合、TCPレイヤは正常に終了します(FINパケットの場合)。RSTパケットが生成されます。

+0

AFAIKは、送信して受信しているソケットを使用する方法はありません。独自のRSTパケットを手作りして相手に送信することもできますが、送信するには別の生のパケットソケットを作成する必要があります。 Linuxには、適切に特権を持つプロセスが任意の接続を閉じるために使用できる 'SOCK_DESTROY'機能(条件付きでカーネルに含まれています)がありますが、アプリケーションソケットから完全にアウトオブバンドです。とにかくRSTで終了したいのはなぜですか? –

+2

SO_LINGERソケットオプションをタイムアウトゼロで試すことができます。[いくつかのリソースに従って](http://stackoverflow.com/questions/3757289/tcp-option-so-linger-zero-when-its-required)それはRSTを生成しますパケットの代わりにFINを使用します。 –

+0

@SlavaBacherikovありがとう、それはコードで動作します: '$ socket = IO :: Socket :: INET-> new(Listen = 1、ReuseAddr => 1、LocalPort => ...、...); $ client = $ socket-> accept(); $ client-> sockopt(SO_LINGER、pack( 'II'、1、0)); close $ client'を実行します。 curlとwgetは常に戻りコード56と4でこの状態を処理します。しかし、netcatは非決定的に "接続によって拒否された接続"を検出しますが、時にはそうではありません。 – bandie

答えて

1

使用しているOSを正確に指定していません。私は、LinuxにはTCP接続をリセットするAPIコールがあることがわかりました。どのように移植性があるのか​​わかりません。これを行う方法は、すでに接続されているソケットでconnectシステムコールを使用することですが、今回はファミリでAF_UNSPECを使用します。

このようにソケットをリセットした後でも、別のconnectコールでソケットを接続することさえ可能です。

int main(int argc, char** argv) 
{ 
    int fd = socket(AF_INET6, SOCK_STREAM, 0); 

    while (1) { 
    struct sockaddr_in6 sockaddr = { 
     .sin6_family = AF_INET6, 
     .sin6_port = htons(80), 
     .sin6_flowinfo = 0, 
     .sin6_scope_id = 0, 
    }; 
    struct timespec s = { 
     .tv_sec = 2, 
     .tv_nsec = 0, 
    }; 

    /* Connect to port 80 on localhost */ 
    inet_pton(AF_INET6, "::1", &sockaddr.sin6_addr.s6_addr); 
    connect(fd, (struct sockaddr*)&sockaddr,sizeof(sockaddr)); 
    nanosleep(&s, NULL); 

    /* Reset previously connected socket */ 
    sockaddr.sin6_family = AF_UNSPEC; 
    connect(fd, (struct sockaddr*)&sockaddr,sizeof(sockaddr)); 
    nanosleep(&s, NULL); 
    } 
} 
+0

あなたの 'connect AF_UNSPEC'ソリューションをipv4リスニングシナリオでもテストしました。この場合、' listen'ソケットではなく 'accept'で返されたソケットを再接続する必要があります。 – bandie

関連する問題