2016-07-21 2 views
1

응용 프로그램 수준에서 accept ed 소켓을 Perl 또는 C에서 IO :: Socket :: INET으로 재설정하는 방법?응용 프로그램에서 TCP 소켓 연결 재설정

programm에 bind ING가있다

, listen TCP 포트에 보내고, 그리고 accept이 후, 클라이언트 연결이야 그것이 read들과 write의 일부 데이터. 소켓을 close 또는 shutdown으로 간단히 설정하면 TCP 레이어가 정상적으로 종료됩니다 (FIN 패킷 사용). RST 패킷을 생성합니다.

+0

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

위대한 나는 ipv4 리스닝 시나리오에서도'connect AF_UNSPEC' 솔루션을 테스트했습니다.이 경우'listen' 소켓이 아닌'accept'가 리턴 한 소켓을 재 연결해야합니다. – bandie

관련 문제