2013-12-09 3 views
0

서버가 클라이언트의 메시지를 처리하고 백업 서버에 복제하는 클라이언트 - 서버 C 프로젝트를 작성하고 있습니다. 잘 작동하지만 프로젝트 (대학 프로젝트)의 포인트 중 하나는 오류 (이 경우 백업 서버가 죽어가는)에 대비해야한다는 것입니다.C (Linux) 소켓 검사

은 내 복제 기능에서이있다 :이 즉시 백업 서버가 사망 한 바와 같이, 제 1 write() 실패했는데

int table_skel_replicate(struct message_t *msg, int sockSecundario){ 
    char *msg_buf; 
    int buf_size_net = 0; 
    int buf_size=0; 
    int okk; 

    struct sockaddr_in server; 

    msg->opcode--; 

    buf_size = message_to_buffer (msg, &msg_buf); 

    buf_size_net = htonl(buf_size); 

    okk = write(sockSecundario, &buf_size_net, sizeof(int)); 

    if(okk == -1 || okk == 0) { 
     msg->opcode++; 
     return okk; 
    } 

    okk = write_all (sockSecundario, msg_buf, buf_size); 

    if(okk == -1) { 
     msg->opcode++; 
     return okk; 
    } 

    okk = read (sockSecundario, &buf_size_net, sizeof(int)); 

    if(okk == -1 || okk == 0) { 
     msg->opcode++; 
     return okk; 
    } 

    buf_size = ntohl(buf_size_net); 
    msg_buf = malloc (buf_size); 

    okk = read_all(sockSecundario, msg_buf, buf_size); 

    msg->opcode++; 

    return okk; 
} 

. 그러나 그것은 doesnt한다. 대신에 write_all() 함수 (길이가 긴 경우에는 write()while 안에 있음)로 이동하고 첫 번째로 write()에서 사망합니다. checksockopt() 함수를 사용해 보았지만 ok로 상태를 반환합니다 ...

주 응용 프로그램은 단순히 닫힙니다. 어떤 도움을 주셔서 감사합니다 ...

+2

** 에러가 발생할 때마다 ** write()를 호출 할 필요가있다. 백업 서버는'write()'호출 쌍 사이에서 언제든지 죽을 수있다. 가능한 모든 오류를 코드에서 정상적으로 처리해야합니다. –

+0

버퍼링으로 인해 연결이 다른 쪽 끝에서 중단 된 후 쓰기가 성공할 수 있습니다. 후속 쓰기가 결국 실패합니다. 그래서'write()'리턴을 체크 할 필요가있다. – EJP

+0

OP는'write' 리턴을 체크하는 것처럼 보입니다 - 아마'write_all'에서도 마찬가지 일 것입니다. 문제는 OP가 정확히 무엇이 실패해야 하는지를 확실하게 만드는 이유입니다. 첫 번째 쓰기는 성공하지만 RST를 이끌어 내고 EPIPE로 실패 할 후속 쓰기입니다. 그래서 이것은 예상 된 행동 일 수 있습니다. – Duck

답변

0

write() 호출에 대한 검사는 SIGPIPE로 인해 프로그램이 종료되기 때문에 아마도 효과가 없습니다. man 2 write :

FD는 그 판독 끝 폐쇄 파이프 나 소켓에 연결된다. 이런 일이 생기면 쓰기 과정에는 SIGPIPE 신호가 수신됩니다. (따라서, 기입 반환 값은 프로그램이 블록을 포착하거나 신호를 무시 만 경우에 볼 수있다.)

쉽게이를 방지하기 는 모든

write(sockSecundario, …, …) 

의해 대체

send(sockSecundario, …, …, MSG_NOSIGNAL)