2013-02-09 3 views
0

여러 클라이언트가 연결되는 클라이언트 서버 채팅 프로그램의 클라이언트 측 구현에 문제가 있습니다. 문제는 내가 가로 질러가는 것이다. 정확하게 (다른 클라이언트에게 메시지를 보내고) 동시에 (다른 클라이언트에서 메시지를 채팅하는) 어떻게해야 하는가? 무슨 일이 일어나고 있는지 나는 항상 데이터를 보내고 결코 읽지 않는다는 것입니다. 나는 포크를 들고 읽어야하고 다른 쪽은 보내야합니까? 여기 c 소켓 : recv 및 데이터 동시 전송

은 관련 코드입니다

클라이언트 측

while(1) { 

    fd_set rfds, wfds; 
    FD_ZERO(&rfds); 
    FD_ZERO(&wfds); 

    FD_SET(serverSocket, &rfds); 
    FD_SET(serverSocket, &wfds); 

    if(select(serverSocket+1, &rfds, &wfds, NULL, NULL) < 0) { 
     perror("select"); 
     exit(-1); 
    } 

    if (FD_ISSET(serverSocket, &rfds)) { 
    // we got data, read it 
    } 
    if (FD_ISSET(serverSocket, &wfds)) { 
    printf(">"); 

    // read keyboard 
    sendLen = 0; 
    while ((cmd[sendLen] = getchar()) != '\n') 
     sendLen++; 
    cmd[sendLen] = '\0'; 

    // send the data 
    } 
} 
+0

별도로 읽기 및 쓰기를 위해 2 개의 다른 스레드를 사용해 볼 수 있습니까? – Ganesh

답변

0

당신은, 다음, 그들에게 문자를 읽고 버퍼뿐만 아니라 선택의 파일 기술자 0 (표준 입력)를 넣어야 때 소켓은 쓰기 위해 사용 가능하며, 버퍼 전체에 복사하십시오. 이 방법으로 표준 입력을 항상 읽지 않게 할 수 있습니다.

뿐만 아니라 때 사용자 유형 뭔가를 반환합니다

FD_SET(0, &rfds); 

그래서 선택

를 추가합니다.

또한 stdin을 비 차단으로 설정하려면 fcntl을 사용해야합니다.

while(read(0,buffer+filled,1)>0) {} 

하면 버퍼가 가득 경우 루프를 종료하려면 다른 조건을 넣어해야합니다 : 그때마다 선택 표준 입력에 데이터가 그런 일을 할입니다을 알려줍니다.

소켓에 쓸 수있는 시간은 버퍼에있는 바이트 수의 크기이고, 버퍼에 모든 바이트가 기록되었는지 확인하거나 버퍼의 시작 부분에 남은 바이트를 이동합니다 .

그 동안 (getchar())이 메시지를 수신하지 못하도록 차단하고 있습니다.

+0

그걸 좀 자세히 설명해 주실 수 있습니까? – theStig

+0

좋아, 해결해야 할 작은 사소한 문제 외에 거의 작동합니다. 아무 래도 클라이언트에게 알릴 필요가 있습니다 (printf (">")를 주목하십시오).하지만 무슨 일이 일어나고있는 것은 명령문에 줄 바꿈이 없으므로 클라이언트가 반환을 얻을 때까지 클라이언트에 출력되지 않습니다. 키. – theStig

+0

stdin을 의미 할 때 STDIN_FILENO가 "0"보다 조금 더 분명하다고 말할 수 있습니다. –