2012-03-10 3 views
6

우분투 컴퓨터에서 파이썬 2.7을 사용하고 있습니다.소켓 연결을 시도 할 때 ECONNABORTED는 무엇을 의미합니까?

클라이언트가 서버에 연결을 시도합니다. 나는 비 차단 소켓에 대해 기대되는 EINPROGRESS를 얻는다.

가 연결이 성공 여부를 확인하기 위해, 나는 {연결}에 대한 man 페이지가 제안 무엇 :

# EINPROGRESS The socket is nonblocking and the connection cannot be 
# completed immediately. It is possible to select(2) or poll(2) for 
# completion by selecting the socket for writing. After select(2) 
# indicates writability, use getsockopt(2) to read the SO_ERROR option at 
# level SOL_SOCKET to determine whether connect() completed successfully 
# (SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual error 
# codes listed here, explaining the reason for the failure) 

서버가 오프라인이 나에게 ECONNREFUSED을 제공합니다. 여태까지는 그런대로 잘됐다.

연결이 실패하면 몇 번 다시 시도하고 싶습니다.

문제 : 두 번째 동일한 소켓에 연결하려고하면 {connect}이 (가) ECONNABORTED를 보냅니다. 이것은 {connect}의 man 페이지에 없습니다. 무슨 뜻이에요?

+1

내가이 일을한다고해도, 내가 너라면, 나는하지 않을 것이다. 나는 소켓 API가 기술적으로 한번 전에 연결에 실패한 소켓을 재사용 할 수 있는지 여부를 모르지만 리눅스는 마음에 들지 않는 반면 MacOS에서는 EINVAL을 얻는다. 매 소켓마다 새 소켓을 엽니 다. – Celada

답변

11

ECONNABORTED은 Linux 커널 소스 소켓 코드의 두 위치에 설정됩니다.

errno man 페이지 당으로

/include/asm-generic/errno.h

#define ECONNABORTED 103 /* Software caused connection abort */

first/그물/소켓에 콜 accept4을 정의하는 기능입니다. c.

관련 소스 코드

1533   if (upeer_sockaddr) { 
1534     if (newsock->ops->getname(newsock, (struct sockaddr *)&address, 
1535           &len, 2) < 0) { 
1536       err = -ECONNABORTED; 
1537       goto out_fd; 
1538     } 
1539     err = move_addr_to_user((struct sockaddr *)&address, 
1540           len, upeer_sockaddr, upeer_addrlen); 
1541     if (err < 0) 
1542       goto out_fd; 
1543   } 

논리의 관련 설명은 다음과 같습니다.

사용자 공간의 피어 소켓의 주소가 으로 정의되고 새 소켓에 이름이없는 경우 오류 상태를 ECONNABORTED으로 설정하고 out_fd 레이블로 이동하십시오.

second은 기호 inet_stream_connect/net/ipv4/af_inet.c에 정의하는 기능을합니다.

관련 소스 코드

645   /* Connection was closed by RST, timeout, ICMP error 
646   * or another process disconnected us. 
647   */ 
648   if (sk->sk_state == TCP_CLOSE) 
649     goto sock_error; 

662 sock_error: 
663   err = sock_error(sk) ? : -ECONNABORTED; 
664   sock->state = SS_UNCONNECTED; 
665   if (sk->sk_prot->disconnect(sk, flags)) 
666     sock->state = SS_DISCONNECTING; 
667   goto out; 

논리의 관련 설명은 다음과 같습니다.

inet_stream_connectsock_error 레이블에 goto가있는 유일한 코드는 소켓이 RST, 시간 초과, 다른 프로세스 또는 오류로 종료되었는지 확인하는 것입니다. sock_error 라벨 우리는 소켓 오류 보고서를 복구 할 수있는 경우에

, 나는 또한 새로운 소켓 매번 여는 것이 좋습니다 Celada의 코멘트처럼 ECONNABORTED

에 그렇지 않으면 오류 상태, 그렇게.

+0

달콤한. 나는 리눅스 커널이 많은 것을 가지고 있다는 것을 몰랐다. :). 필자는 "소프트웨어로 인해 연결이 중단되었습니다"라는 사실을 완전히 과소 평가하고 있었지만 인용 한 코드에 비추어보다 의미가 있습니다. 나는 두 번째 것이 나의 경우에 적용된다고 생각한다. 나는 그때 새로운 소켓을 만들 것이다, 문제 없다. – Niriel

0

errno의 매뉴얼 페이지를 참조하십시오. FreeBSD에서 이것을 intro (2)로 찾을 수 있습니다. 그것은 말합니다 :

53 ECONNABORTED 소프트웨어로 인해 연결이 중단되었습니다. 호스트 시스템 내부에서 연결 중단이 발생했습니다.

왜 이런 일이 발생했는지에 관해서는 리눅스 커널 소스에서 소켓을 조사해야합니다. FreeBSD에서 accept 만 반환 ECONNABORTED 것 같습니다.

관련 문제