使用している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);
}
}
AFAIKは、送信して受信しているソケットを使用する方法はありません。独自のRSTパケットを手作りして相手に送信することもできますが、送信するには別の生のパケットソケットを作成する必要があります。 Linuxには、適切に特権を持つプロセスが任意の接続を閉じるために使用できる 'SOCK_DESTROY'機能(条件付きでカーネルに含まれています)がありますが、アプリケーションソケットから完全にアウトオブバンドです。とにかくRSTで終了したいのはなぜですか? –
SO_LINGERソケットオプションをタイムアウトゼロで試すことができます。[いくつかのリソースに従って](http://stackoverflow.com/questions/3757289/tcp-option-so-linger-zero-when-its-required)それはRSTを生成しますパケットの代わりにFINを使用します。 –
@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