2011-12-29 2 views
1

한 번에 여러 클라이언트를 처리하는 서버를 작성하려고합니다. 분명히 select을 사용해야합니다. 나는 많은 튜토리얼을 발견했지만 그들 중 누구도 글을 다룰 수 없다.여러 클라이언트가있는 서버 - select()를 사용하여 작성하기

나는 어떻게 데이터를 읽어야하는지 알지만, 내 '루프'에서 클라이언트에게 다시 쓰는 것을 처리하는 적절한 방법은 무엇입니까?

미리 감사드립니다.

답변

2

특정 소켓으로 보내려는 데이터가있는 경우 해당 소켓의 출력 버퍼에 사용 가능한 공간이있을 때 반환하려면 select()가 필요합니다. select()를 수행하는 방법은 select()를 읽기 전용으로 사용하는 것과 비슷하지만 두 번째 fd_set 객체에서 FD_SET을 수행한다는 점만 다릅니다.

int socks[10] = {... some client sockets...} 

while(1) 
{ 
    fd_set readSet, writeSet; 

    FD_ZERO(&readSet); 
    FD_ZERO(&writeSet); 

    int maxSock = -1; 
    for (int i=0; i<10; i++) 
    { 
     FD_SET(socks[i], &readSet); 
     if (socks[i] > maxSock) maxSock = socks[i]; 

     if (IHaveDataToSendToThisSocket(i)) // implement this function as appropriate to your program 
     { 
     FD_SET(socks[i], &writeSet); 
     if (socks[i] > maxSock) maxSock = socks[i]; 
     } 
    } 

    int ret = select(maxSock+1, &readSet, &writeSet, NULL, NULL); 
    if (ret < 0) 
    { 
     perror("select() failed"); 
     break; 
    } 

    // Do I/O for sockets that are ready 
    for (int i=0; i<10; i++) 
    { 
     if (FD_ISSET(socks[i], &readSet)) 
     { 
     // there is data to read on this socket, so call recv() on it 
     } 

     if (FD_ISSET(socks[i], &writeSet)) 
     { 
     // this socket has space available to write data to, so call send() on it 
     } 
    } 
} 
+0

고맙습니다. 내가 혼란스러워하는 부분은 독서와 함께, (a) 데이터를 기다리고 (b) 그것을 읽는 것입니다. 글쓰기로 쓰여질 데이터가 있는지 어떻게 알 수 있습니까? 나는 이것을 지구상의 벡터처럼 저장해야합니까? –

+0

나에게 보낸 내용에 따라 클라이언트에 다시 써야합니다. 내가 다시 쓸 수 있음을 알리는 신호가 들릴 때까지 어떻게하면 내 읽기 데이터에 액세스 할 수 있습니까? –

+0

소켓에 쓸 데이터가 있는지 여부는 응용 프로그램의 기능에 따라 다릅니다. 귀하의 경우 : 동일한 소켓에서 다른 데이터를 다시 전송하여 서버가 수신 된 데이터에 응답하게하려면 각 소켓에 대해 해당 소켓에 대한 "대화 상태"를 나타내는 데이터 구조가 있어야합니다. –

0

사실 저는 여러분이 select()가 아니라 poll()을 사용하려고한다고 생각합니다. 그러나 이것은 요점입니다. 여러 클라이언트에 쓰려면 블로킹 쓰기를 사용하지 않아야합니다. 특정 데이터가 더 많은 데이터를 소화 할 수 있는지 여부를 감지하지 못하게 될 수 있으므로 작성시 poll() (또는 select())을 사용할 필요가 없을 수도 있습니다. 그러나 다른 속도로 데이터를 소비하는 클라이언트를 준비하려면 클라이언트가 더 많은 데이터를 소화 할 수있을 때 알림을 수신하려고 할 수 있습니다.

poll() 또는 select()는 읽기 버퍼에서 사용 가능한 데이터 또는 쓰기 버퍼에서 사용 가능한 공간에 대해 알릴 수 있습니다. 사용법은 다른 플래그를 설정해야한다는 것을 제외하면 거의 동일합니다.

관련 문제