한 번에 여러 클라이언트를 처리하는 서버를 작성하려고합니다. 분명히 select
을 사용해야합니다. 나는 많은 튜토리얼을 발견했지만 그들 중 누구도 글을 다룰 수 없다.여러 클라이언트가있는 서버 - select()를 사용하여 작성하기
나는 어떻게 데이터를 읽어야하는지 알지만, 내 '루프'에서 클라이언트에게 다시 쓰는 것을 처리하는 적절한 방법은 무엇입니까?
미리 감사드립니다.
한 번에 여러 클라이언트를 처리하는 서버를 작성하려고합니다. 분명히 select
을 사용해야합니다. 나는 많은 튜토리얼을 발견했지만 그들 중 누구도 글을 다룰 수 없다.여러 클라이언트가있는 서버 - select()를 사용하여 작성하기
나는 어떻게 데이터를 읽어야하는지 알지만, 내 '루프'에서 클라이언트에게 다시 쓰는 것을 처리하는 적절한 방법은 무엇입니까?
미리 감사드립니다.
특정 소켓으로 보내려는 데이터가있는 경우 해당 소켓의 출력 버퍼에 사용 가능한 공간이있을 때 반환하려면 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
}
}
}
사실 저는 여러분이 select()가 아니라 poll()을 사용하려고한다고 생각합니다. 그러나 이것은 요점입니다. 여러 클라이언트에 쓰려면 블로킹 쓰기를 사용하지 않아야합니다. 특정 데이터가 더 많은 데이터를 소화 할 수 있는지 여부를 감지하지 못하게 될 수 있으므로 작성시 poll() (또는 select())을 사용할 필요가 없을 수도 있습니다. 그러나 다른 속도로 데이터를 소비하는 클라이언트를 준비하려면 클라이언트가 더 많은 데이터를 소화 할 수있을 때 알림을 수신하려고 할 수 있습니다.
poll() 또는 select()는 읽기 버퍼에서 사용 가능한 데이터 또는 쓰기 버퍼에서 사용 가능한 공간에 대해 알릴 수 있습니다. 사용법은 다른 플래그를 설정해야한다는 것을 제외하면 거의 동일합니다.
고맙습니다. 내가 혼란스러워하는 부분은 독서와 함께, (a) 데이터를 기다리고 (b) 그것을 읽는 것입니다. 글쓰기로 쓰여질 데이터가 있는지 어떻게 알 수 있습니까? 나는 이것을 지구상의 벡터처럼 저장해야합니까? –
나에게 보낸 내용에 따라 클라이언트에 다시 써야합니다. 내가 다시 쓸 수 있음을 알리는 신호가 들릴 때까지 어떻게하면 내 읽기 데이터에 액세스 할 수 있습니까? –
소켓에 쓸 데이터가 있는지 여부는 응용 프로그램의 기능에 따라 다릅니다. 귀하의 경우 : 동일한 소켓에서 다른 데이터를 다시 전송하여 서버가 수신 된 데이터에 응답하게하려면 각 소켓에 대해 해당 소켓에 대한 "대화 상태"를 나타내는 데이터 구조가 있어야합니다. –