묻고 답해요
131만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
하트비트 시 서버에서의 연결 종료
안녕하세요 좋은 강의감사합니다.소켓연결 종료 시 클라이언트가 먼저 끊게 유도하라고 하셨는데만약 서버에서 주기적으로 N초마다 하트비트를 보내고 클라이언트에서 응답이 없을 경우 서버에서 연결을 종료해야 하지 않나요??? 혹시 이 상황에선 보편적으로 어떻게 하는지 궁금합니다.
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
강사님 질문 드립니다.
제공해주신 멀티스레드 소켓 프로그램에 LPVOID 형을 가지는 매개변수에 일반 변수를 지정하셨는데 LPVOID 는 포인터와 일반변수 모두 가능 한 건지요?주신 프로그램을 보면 SOCKET hClient = 0; // SOCKET 형 변수를 선언 hThread = ::CreateThread( NULL, 0,ThreadFunction, (LPVOID)hClient, // 주소가 아닌 값을 지정0, &dwThreadID); 만약 가능하다면 내부적으로 어떻게 가능한지 확인 부탁드려봅니다. 늘 좋은 강의 감사합니다. 강사님
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
소켓 입/출력 설계 정리
안녕하세요. 선생님!프로토콜 설계관련 큰 흐름을 정리 해보고 있습니다. 주요 포인트는 서버에서 관리(TCP로 연결된 소켓)하고있는 클라이언트들의요청을 어떤 구조로 처리할지?총 3가지 형태로 정리되었습니다.1. 블록강의 : 멀티쓰레드 채팅서버 구조(블록 소켓)2. 논블록강의에는 없지만, 하나의 쓰레드에서 여러 논블록 소켓들 돌며 Receive를 확인하는 구조3. 비동기강의 : IOCP기반 채팅서버(클라이언트 수신처리를 OS에 등록하여 콜백 받는구조)궁금한 부분은다양한 프로토콜 설계를 "큰 주제"로 나눈다면블록/ 논블록/ 비동기 이렇게 3가지 형태로 나누어도 크게 문제가 없을 지 궁금합니다.
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
멀티스레드 기반 서버 관련 질문..!
안녕하세요 널널한 개발자님, 덕분에 수업 잘 듣고 있습니다. :)현재 멀티스레드 채팅 클라이언트, 서버 기반 수업을 듣고 해당 구조를 변경해서 작은 빙고 게임을 만들어 보고 있습니다. 해당 게임의 큰 틀을 짧게 요약하자면클라 - 연결 요청 -> 서버 - 확인 후 번호 전달3번째 클라 - 연결 요청 -> 서버 - 확인 후 모든 클라에게 보드판 및 게임 순서를 전달클라 - 게임 순서에 맞는 클라가 빙고판 번호를 입력 -> 서버 - 확인 후 보드판 정보 업데이트 및 다시 모든 클라에게 전달 .... 이런 식으로 게임이 진행됩니다, 2번 동작까지는 잘 진행이 되는데 '문제'는 3번 순서에서 클라가 빙고판 번호를 입력했을 때 서버로 전달이 되지 않아 보드판 정보 업데이트가 되지 않고 있습니다..클라에서 서버로 메시지를 전달할 때 버퍼의 내용은 문제가 없었는데, 이상하게 서버로 전달만 하면 빈 버퍼가 전달이 되네요..혹시나 서버 버퍼에서 소켓 입출력 버퍼가 Nagle 알고리즘에 의해 서버 프로세스로 전달이 되지 않은 건가 싶어서 소켓의 TCP_NODELAY 옵션도 설정해보았는데, 해결이 되지 않았습니다. whireShark를 이용해서 확인을 하고 있긴 한데, 아직 제 수준에서는 내용을 파악하기 힘드네요.. 널널한 개발자님이라면 이런 상황에서 어떻게 문제를 해결하실 건가요??
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
TIME_WAIT 관련 문의드립니다.
안녕하세요."에코 클라이언트/서버 테스트 및 Wireshark로 확인" 강의에서 제공해 주신 예제 프로그램을 실행해 보다가 TIME_WAIT 관련하여 몇 가지 궁금한 것이 있어 문의드립니다. (1) Client 쪽에서 여러 번 접속을 하고 종료를 할 경우, 아래 이미지처럼 생성된 Port 별로 TIME_WAIT 상태로 있고, 어느 정도 시간이 지나면 모두 없어지던데 이건 CLOSED 상태로 된 것으로 보면 되는 건가요? (2) 제공해 주신 수업 자료에서의 TCP 상태 전이도에서 TIME_WAIT에서 CLOSED 상태로 가는 화살표에 있는 Timeout은 운영체제에서 관리하는 건가요? 아니면 예제 프로그램에서 사용된 Socket 관련 함수에서 제어가 되는 건가요? 감사합니다.
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
강사님 강의자료 인쇄용으로 부탁드립니다.
강사님 강의자료 인쇄용으로 부탁드립니다!
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
bind 함수 관련 궁금증
안녕하세요.강의 수강 중 궁금한 점이 있어서 질문드립니다! TCP 에코 서비스 전체 흐름 수업 중에 서버에서 bind 함수가 필요한 이유를 듣고 문득 궁금해졌습니다. bind 함수가 소켓이라는 추상적인 객체에 TCP 프로토콜을 붙여서 구체화를 시켜주는 함수로 이해했습니다. 그렇다면, 클라이언트도 bind라는 함수가 필요하지 않나 생각이 들었습니다.서버와 통신을 한다면 결국 클라이언트도 IP와 port 정보가 필요하다고 생각하는데 왜 클라이언트는 따로 bind 함수를 호출하지 않는지 궁금합니다!
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
스마트포인터 사용여부 및 가능성
안녕하십니까 선생님. 훌륭한 강좌 잘 들었습니다. 비동기 콜백 부분에서 버퍼와 오버랩드구조체를 동적할당하고 콜백함수에 주소를 주고 다쓴후에 딜리트를 하는 방식을 유니크나 쉐어드포인터 같은 스마트포인터로 대체가 가능할까요?특히 쉐어드는 잘만쓰면 정말유용할것 같긴한데 서버개발할때 레퍼런스 카운팅에 대한 아토믹연산의 오버헤드에 대해 감당할만하다고 생각하시는지요?또한 스마트포인터를 쓰고싶어도 콜백함수로 등록가능한 함수형태가 정해져있어서 스마트포인터 그 자체를 넘겨줄순없는것같은데혹시 방법이있다면 조언좀 부탁드리겠습니다.감사합니다.
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
CreateThread()를 사용하여 클래스의 멤버함수를 실행할 수 는 없나요?
수업을 듣고 따로 서버코드를 만들어 보려는 중 잘 안돼서 질문 드립니다.class Server { private: SOCKET listenSocket; std::list<SOCKET> listClients; SOCKADDR_IN serverAddr; public: Server(); Server(USHORT port, IN_ADDR addr); void Bind(); void Listen(); DWORD WINAPI ThreadAcceptLoop(LPVOID pParam); void AcceptClient(); void ReleaseServer(); ~Server(); };main 함수에서 Server클래스의 객체를 만들어서 서버를 실행하는 로직을 구현하고 있습니다.Server클래스의 AccpetClient()에서 CraeteThread()를 사용하여 ThreadAcceptLoop()를 실행하는 쓰레드를 만들어서 클라이언트의 요청을 Accept()하려고 합니다.하지만 CreateThread()함수에서 E0167 DWORD (__stdcall Server::*)(LPVOID pParam) 형식의 인수가 LPTHREAD_START_ROUTINE 형식의 매개 변수와 호환되지 않습니다. 라는 오류와 함께 컴파일이 되지 않습니다.찾아본 결과 함수를 static으로 선언하던지 전역함수를 사용하라고 합니다. 제가 하려던것처럼 클래스의 멤버함수를 실행할 수는 없나요??
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
0강 Win32 작업자 스레드 동기화 9:33~
DWORD WINAPI ThreadFunction(LPVOID pParam) { puts("*** Begin Thread ****"); for (int i = 0; i < 5; ++i) { printf("[Worker thread] %d\n", i); ::Sleep(1); } //스레드가 끝나기 전에 이벤트를 세트한다. puts("종료 이벤트 세트 전"); //이 함수를 호출하면 _tmain() 함수의 //WaitForSingleObject() 함수가 반환한다! ::SetEvent((HANDLE)pParam); puts("종료 이벤트 세트 후"); puts("**** End Thread ****"); return 0; }for (int i = 0; i < 5; i++) { printf("[Main thread] %d\n", i); //i값이 3이면 이벤트가 세트되기를 무한정 기다린다! if (i == 3 && ::WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0) { puts("종료 이벤트를 감지했습니다!"); ::CloseHandle(hEvent); hEvent = NULL; } }3일 때 worker 스레드가 실행되는 조건문 하에서Main함수가 2일 때도 반환되고 0일 때도 반환됩니다.말씀해주신대로 3일 때 반환되는 경우도 있지만 보장되지 않고 빈번하게 아래 케이스처럼 반환되는 경우가 있습니다.(디버그 모드, 릴리즈 모드 모두에서)이는 무슨 이유 때문인지 궁금합니다. case1[Main thread] 0[Main thread] 1[Main thread] 2*** Begin Thread ****[Worker thread] 0[Main thread] 3[Worker thread] 1[Worker thread] 2[Worker thread] 3[Worker thread] 4종료 이벤트 세트 전종료 이벤트 세트 후**** End Thread ****종료 이벤트를 감지했습니다![Main thread] 4 case2[Main thread] 0*** Begin Thread ****[Main thread] 1[Main thread] 2[Worker thread] 0[Main thread] 3[Worker thread] 1[Worker thread] 2[Worker thread] 3[Worker thread] 4종료 이벤트 세트 전종료 이벤트 세트 후**** End Thread ****종료 이벤트를 감지했습니다![Main thread] 4
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
이벤트 기반 비동기 파일 입/출력 (예제 포함)
안녕하세요 선생님 DWORD dwRead; OVERLAPPED aOl[3] = { 0 }; HANDLE aEvt[3] = { 0 }; //세 번의 비동기 쓰기 완료를 확인하기 위한 이벤트 객체를 생성한다. for (int i = 0; i < 3; ++i) { aEvt[i] = ::CreateEvent(NULL, FALSE, FALSE, NULL); aOl[i].hEvent = aEvt[i]; } //비동기 쓰기가 시작될 지점을 기술한다. //두 번째 쓰기는 세 번째 쓰기보다 나중에 이루어질 가능성이 높다. aOl[0].Offset = 0; //파일의 시작. aOl[1].Offset = 1024 * 1024 * 128; //5MB aOl[2].Offset = 16; //16바이트 //세 번의 비동기 쓰기를 순차적으로 수행한다. for (int i = 0; i < 3; ++i) { printf("%d번째 중첩된 쓰기 시도.\n", i); ::WriteFile(hFile, "0123456789", 10, &dwRead, &aOl[i]); //정상적인 경우 쓰기 시도는 지연(보류)된다! if (::GetLastError() != ERROR_IO_PENDING) exit(0); }여기서 dwRead가 얼마나 쓰였는지 확인하는 바이트수를 나타낸다고 하는데 만약 쓰고 싶다면 //세 번의 비동기 쓰기가 완료되기를 대기한다. DWORD dwResult = 0; for (int i = 0; i < 3; ++i) { dwResult = ::WaitForMultipleObjects(3, aEvt, FALSE, INFINITE); printf("-> %d번째 쓰기 완료.\n", dwResult - WAIT_OBJECT_0); } sizeof("0123456789") == dwRead; 이런식으로 마지막에 비교할때 쓰이는건가요?
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
파일 송수신 테스트
안녕하세요 선생님 질문이 있습니다. 4:17에서client에서 File List를 요구한 다음 server에서 보내는 패킷에서 사이즈가 796인게 MYCMD cmd; cmd.nCode = CMD_SND_FILELIST; cmd.nSize = sizeof(g_flist)+sizeof(g_aFInfo);MYCMD의 사이즈가 맞나요....?
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
파일 송신 서버 제작 (예제 포함)
안녕하세요 선생님 질문이 있습니다. 파일 송신을 할때 server가 100을 보내도 client가 빠르게 처리 못하는 경우 50정도 만간다는 예시에서나머지 50은 tcp buffer(OS쪽) 에 남겨져 있다고 봐야하는건가요? 어디서 머무르고 있는것인가요?
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
iocp 모델 설명과정에서 궁금한 부분이 있습니다.
강의 중 os가 vms 메모리에 lock을 걸어 커널에서 다루는 것이다라고 말씀하신 이후 "유저 모드 어플리케이션을 논 페이즈드 풀 메모리로 바꾸고... " 라는 식으로 표현하신 부분이 있는데 이 부분이 잘 이해되지 않습니다. (11분 10초)이 부분은 유저 모드의 메모리 영역을 커널과 공유하여 불필요한 메모리 복사를 방지한다. 라고 이해하면 될까요?
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
프로토콜이 없는 파일 송신, 수신 예제에서 같은 오류가 발생하고 있습니다.
FileSenderCRLFileReceiver 수업자료에서 이런 오류가 발생 합니다.별도로 수정한 부분은 없습니다..
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
recv() 함수가 아무 응답도 보내지 않는 이유는 무엇인가요?
break point를 통해 echo server 과정을 조정하던 중 send()를 보낼 때 ack 응답이 돌아온다는 것을 알게되었습니다.저는 recv()로 데이터를 받아 ack 응답을 보내는 줄만 알았는데 아니였더군요...recv()로 응답하지 않는다면 데이터가 제대로 전송되어 버퍼에 저장되었음을 알 수 없는 것 아닌가요?send()에서만 응답 받았음을 알리는 이유가 궁금합니다.
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
send, recv 함수
char buf[] = "data"; int sendSize = 0; int total = 0; while ((sendSize = send(socket, buf + total, sizeof(buf) - total, 0) > 0 && total < sizeof(buf)) { total += sendSize; }데이터를 송수신할 때 송수신 함수는 주고받고 싶은 만큼의 데이터가 모두 전달되지 않더라도 완료될 수 있으니까데이터를 송수신할 때는 한 번의 함수호출이 아닌 위와 같이 여러 번의 함수호출로 완전한 데이터 송수신을 하는 게 맞나요??(코드는 송신할때의 상황이지만 수신도 서로 약속한 길이의 데이터를 주고받을 때 마찬가지인지 궁금합니다.)
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
소켓에 대한 질문드립니다.
강사님. 항상 강의 잘 보고 있습니다.궁금한게 있어서 질문 드립니다.제가 이해하기론 클라이언트가 하나 연결될 때마다 서버는 새로운 소켓을 만들고 거기에 클라이언트를 연결한다?로 이해하고 있는데요.만약 제가 이해한 것이 맞다면 새로 만들어진 소켓에 새 포트번호가 매핑되서 클라이언트랑 통신을 해야할 것 같은데 wireshark로 확인해보면 25000로 클라이언트와 통신을 하고 있어서요.제가 놓친 것이 무엇인가요?
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
RUDP 질문드립니다
게임 서버 같은 경우에 RUDP를 이용하는 방식이 듣고보니 되게 좋은 것 같아서 구현하려고 하는데 생각 이상으로 고려해야할게 너무 많아서 혹시 저런 것을 구현하는 이론이 있을까요?
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
클라이언트가 먼저 연결종료를 해야한다고 하신부분 질문입니다.
클라이언트가 만약 소켓 연결을 정상 종료하지 않고 프로그램을 끄게 되는 경우 예컨데 정전으로 인해 클라이언트 PC가 종료됐다면 서버는 알턱이 없으니 결국 TimeOut을 체크해서 서버가 연결을 종료해야할 것 같은데 맞을까요?제 생각엔 위와 같은 흐름으로 진행되고 다른 방법은 떠오르지 않는데 혹시 대응할 수 있는 방법이 있을까요?