티스토리 뷰

프로그램이 수행해야 할 일

서버

클라이언트로부터 메세지를 수신해서 다른 클라이언트들에게 뿌려주는 단순한 echo 기능을 수행한다.

클라이언트

콘솔 화면에서 메세지를 입력받아서 서버로 송신하며, 동시에 서버에서 수신받은 메세지를 화면에 출력한다.






서버

리눅스에도 있는 select를 사용해서 각 소켓의 메세지를 수신하고 송신할 수 있지만 winsock에서는 더 사용하기 편하고 강력한 기능을 제공하는 WSAEventSelect를 사용하기로 한다.


클라이언트

서버에서 WSAEventSelect를 사용하여 멀티플렉싱을 구현하였기 때문에 클라이언트에서도 해당 함수를 사용해서 stdin과 소켓의 멀티플렉싱을 구현하려 했으나 windows는 socket과 file을 다르게 관리하기 때문에 위 함수를 사용할 수 없었다.

아래는 멀티쓰레드로 문제를 해결하기까지의 과정이다.

결과적으로 너무 간단하게 해결되었지만 그동안 고생한게 아까우니 정리해보자.


원하는 결과

WSAWaitForMultipleEvent()가 stdin에서 발생하는 이벤트를 감지하는 것

정확히는 문자를 입력하고 enter를 입력했을 때 발생하는 이벤트를 감지해서 그동안 입력한 데이터를 읽어서 소켓으로 전송하는 것


시도해 본 방법

WSAWaitForMultipleEevents()가 STD_INPUT_HANDLE의 이벤트를 기다리도록 해보자

eventList에 


hEvents[numSockets] = GetStdHandle(STD_INPUT_HANDLE);


위처럼 STD_INPUT_HANDLE을 넣고 대기시켜보니 키보드를 한번만 입력해도 마치 트리거가 켜진 것 처럼 이벤트가 계속 발생했다.

WSAResetEvent() 등으로 이벤트를 unsignal시켜보려 했지만 실패했다.

// 그냥 ResetEvent()로 리셋시켰더니 unsignal되긴 했지만 keydown, keyup 등 모든 키보드 이벤트에 동작해서 사용할 수 없었다.


루프 내에서 gets()로 입력을 받아보자

WSAWaitForMultipleEvents()의 대기가 끝나고 아래로 내려오면 메세지를 수신한 뒤 gets()를 만나게 되는데 gets는 입력이 완료될때 까지 block 되기 때문에 메세지를 하나 보낼 때 마다 그동안 쌓였던 메세지를 다 받게돼서 사용할 수 없다.


ioctlsocket이라는 함수가 있던데 입출력비동기소켓으로 만들어준다고 한다. 이게 뭘까


입출력 비동기 모드

서버로부터 수신이 있거나 송신을 하는 동안 프로세스를 일시정지 하도록 하는 것.


원하는 결과는 오히려 동기 모드에 가깝다


시도해 볼 수 있는 다른 방법

WSAWaitForMultipleEevnts가 1ms만 대기하다가 return하고 바로 _getch로 입력 버퍼에서 문자를 가지고 와보자

WSAWaitForMultipleEvents의 대기시간을 1로 설정하고 루프 내에서


if(_kbhit()){

c = _getch();

// do with c

...

}


문제를 너무 비벼서 해결하는 것 같다. 해보진 않았지만 이 방법이 끝까지 잘 동작할 거라는 보장을 못하겠다.

더 좋은 방법을 찾아보자






해결한 방법

_begintrhead로 thread를 새로 만들어서 해당 thread로는 입력을 받고 기존 thread에서는 서버로 부터 수신을 계속 받는다.


 

unsigned __stdcall SendThread(void *s);

 

void main(){

/*

...소켓을 생성하고 서버에 연결하는 등...

*/

// thread 생성

HANDLE sendThread = _beginthreadex(NULL, 0, SendThread, (void*)s, 0, NULL);

 

while(1){

// recv message

/*

...생략...

*/

}

CloseHandle(sendThread);

}

 

unsigned __stdcall SendThread(void *s){

/*

변수 정의 및 초기화 등...

*/

while(1){

// send message

/*

...생략...

*/

}

}


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함