2011-09-12 6 views
1

나는 클라이언트가 쓸 2 피치 (fifo)를 듣는 서버 프로그램을 만들어야하는 숙제로 상당히 큰 프로젝트를 만들고있다.fifo에 syscall이 열려 있지 않습니까?

모든 것이 효과가 있지만 나를 화나게하는 무언가가 있습니다. 클라이언트와 서버 사이의 쓰기/읽기로 구성된 작업을 할 때마다 클라이언트에서 FIFO를 닫으면 서버 "think"처럼 보입니다. 아직도 그 열혈을 열어 놓은 누군가가있다.

이로 인해 서버는 각 작업 후에 64 바이트를 읽으려고 시도하는데, 일반적으로 실패합니다 (0 바이트 읽기). 이 일이 발생 작업 당 하나의 시간, 그것은 고객에게 어떤 문제를 만들지 않습니다

64 바이트를 읽으려고 유지하지 않습니다하지만 정말 이상하다 내가 버그

I의 그 유형을 싫어 열기/닫기 및 고객이 자물쇠를 사용한다는 사실과 관련된 문제라고 생각하십시오.

참고, 열기 조작에 사용되는 플래그는이 의사 텍스트에 지정된

서버 동작 :

Open Fifo(1) for READING (O_RDONLY) 
Open Fifo(2) for WRITING (O_WRONLY) 
Do some operations 
Close Fifo(1) 
Close Fifo(2) 

클라이언트 동작 :

Set a lock on Fifo(1) (waiting if there is already one) 
Set a lock on Fifo(2) (same as before) 
Open Fifo(1) for WRITING (O_WRONLY) 
Open Fifo(2) for READING (O_RDONLY) 
Do some operations 
Close Fifo(1) 
Close Fifo(2) 
Get lock from Fifo(1) 
Get lock from Fifo(2) 

내가 직접 게시 할 수 없습니다 이 코드는 네트워킹에 사용되는 함수를 제외하고 프로젝트가 상당히 크기 때문에 직접 syscall을 사용하지 않기 때문에. 여기 있습니다 :

int Network_Open(const char* path,int oflag) 
{ 
    return open(path,oflag); 
} 

ssize_t Network_IO(int fifo,NetworkOpCodes opcode,void* data,size_t dataSize) 
{ 
    ssize_t retsize = 0; 
    errno = 0; 

    if (dataSize == 0) return 0; 

    while ((retsize = (opcode == NetworkOpCode_Write? write(fifo,data,dataSize) : read(fifo,data,dataSize))) < 0) 
    { 
     if (errno != EINTR) break; 
    } 

    return retsize; 
} 

Boolean Network_Send(int fifo,const void* data,size_t dataSize) 
{ 
    return ((ssize_t)dataSize) == Network_IO(fifo,NetworkOpCode_Write,(void*)data,dataSize); 
} 

Boolean Network_Receive(int fifo,void* data,size_t dataSize) 
{ 
    return ((ssize_t)dataSize) == Network_IO(fifo,NetworkOpCode_Read,data,dataSize); 
} 

Boolean Network_Close(int fifo) 
{ 
    if (fifo >= 0) 
     return close(fifo) == 0; 
} 

감사합니다. 감사합니다.

편집 1 :

클라이언트 출력 :http://pastie.org/2523854 서버 출력 (strace를가) : 제로) (읽기 (차단)에서 반환 된 바이트 http://pastie.org/2523858

+0

Network_Open에서 열려는 플래그는 무엇입니까? – asm

+0

O_RDONLY는 읽기 전용이고 O_WRONLY는 쓰기 만합니다. 다른 것은 –

답변

2

read()의 0 바이트 결과는 다른 프로세스가 완료되었음을 의미합니다. 이제 서버는 원본 파일 설명자를 닫고 FIFO를 다시 열어 다음 클라이언트를 제공해야합니다. 새 파일 설명자로 작업을 시작하면 차단 작업이 다시 시작됩니다.

그것이 작동해야하는 방법입니다.

AFAIK, 0 바이트를 얻은 후에도 파일 디스크립터를 읽으려는 시도는 영구적으로 (또는 파일 디스크립터를 닫을 때까지) 0 바이트를 반환합니다. 다른 프로세스가 FIFO를 열더라도 원래 파일 디스크립터는 EOF를 계속 표시합니다 (다른 클라이언트 프로세스는 서버 프로세스가 FIFO를 열어 읽기를 기다리는 동안 멈추게됩니다).

3

파일의 끝, 즉를 나타냅니다 , 다른 끝이 FIFO를 닫았습니다. 맨페이지를 읽어보십시오.

+0

이걸 이해할 수 있습니다. 쓰기 모드에서 반대쪽 끝에 아무도없는 경우 내 서버가 첫 번째 FIFO를 읽는 이유는 무엇입니까? –

+0

Mh yea하지만 차단 모드에서 설명자를 여는 것이므로이 동작을 이해할 수 없습니다. –

+1

코드의 아무 것도이 동작을 보여줍니다. FIFO를 열고 데이터를 읽으면 결국 0을 읽습니다. 모든 것이 완벽하게 정상입니다. 0을 반환 할 때 당신은 무엇을합니까? 너가 다시 핵폭탄을 열라고 말하고 있니? 고객이 다시 열기 전에? 응용 프로그램에서'strace'를 실행하여 어떤 일이 발생하는지 확인하십시오. – nos

관련 문제