사용중인 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 패킷을 항상 수작업으로 만들어서 동료에게 보낼 수는 있지만, 보내려면 별도의 원시 패킷 소켓을 만들어야합니다. 리눅스는 또한 임의의 연결을 닫기 위해 적절한 권한을 가진 프로세스가 사용할 수있는'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