묻고 답해요
156만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨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을 체크해서 서버가 연결을 종료해야할 것 같은데 맞을까요?제 생각엔 위와 같은 흐름으로 진행되고 다른 방법은 떠오르지 않는데 혹시 대응할 수 있는 방법이 있을까요?
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
질문있습니다
채팅 서버 코드 상에서 쓰레드를 생성한 직후 바로 CloseHandle함수를 호출하여 쓰레드 핸들을 해제해주는 부분이 있는데 쓰레드의 동작이 완료되기 전에 CloseHandle을 해줘도 문제가 없나요??리스닝 소켓과 accept함수로 생성된 소켓의 포트 번호가 25000으로 netstat와 wireshark 상으로 보면 동일하게 나오는데 여러 개의 소켓이 하나의 포트 번호를 공유할 수 있나요?? 아니면 netstat와 wireshark의 편의 기능인가요?? accept하면 랜덤한 포트번호를 할당받아서 소켓에 부여한다고 알고 있어서 질문드립니다 ㅠ리스닝 소켓도 버퍼가 있나요??shutdown(hSocket, SD_BOTH);로 리스닝 소켓을 shutdown해주고 나서 accept를 해봤는데 클라이언트의 접속이 잘 되더군요. 리스닝 소켓의 shutdown은 아무런 효과가 없는 건가요??클라이언트와 연결돼있는 상태에서 closesocket(hSocket);을 해서 리스닝 소켓을 해제해봤더니 서버에 연결돼있는 모든 클라이언트에게 RST가 보내졌습니다.그럼 서버가 종료될 때 클라이언트 연결을 끊으려고 모든 클라이언트 소켓들을 순회하면서 closesocket을 해주는 대신 리스닝 소켓하나만 closesocket을 해주는 방식을 써도 될까요??
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
TCP_NODELAY 옵션
TCP_NODELAY 옵션을 주면 입출력 버퍼를 사용하지 않는다고 하셨는데 입력 버퍼도 사용하지 않나요??맞다면 보내는 측의 send()와 받는 측의 recv()가 1:1 매핑이 되는 건가요?? ( 받는 측에서 TCP_NODELAY 옵션을 줬다면 )
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
질문있습니다
1. send()함수는 패킷을 보내는 함수가 아니라 소켓의 출력 버퍼에 데이터를 쓰는 것이고, recv()함수는 소켓의 입력버퍼에서 데이터를 읽어들이는 거라고 보면 될까요?? 데이터를 모아서 한번에 패킷을 보내는 것이 패킷의 갯수를 줄여서 성능 상의 이점이 있다는 건 알겠지만 데이터를 받을 때도 입력 버퍼에서 모아놓았다가 한번에 읽어들이는 것이 좋다는 것은 잘 모르겠네요...ㅠㅠ데이터를 받을 때 패킷을 보낼 때와 마찬가지로 일정 시간 대기해서 데이터가 쌓이도록 한 다음 읽어들인다는 건가요??
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
IOCP에서 WSASend 사용 관련 및 시간 소요 요청 처리
먼저 좋은 강의 감사드립니다.IOCP를 사용 시 채팅서버에서 수신의 경우는 WSARecv를 사용하였으나, 송신은 일반 send 함수를 사용하고 있습니다.송신의 경우 WSASend를 사용하는 것이 send를 사용하는것 대비 장점이 없는 것인지요?WSASend 사용 관련하여 해당 함수를 사용해야 하는 상황에 대해 설명 부탁드립니다.추가로 IOCP의 thread (GQCS)에서 처리하는 일이 시간이 소요되는 처리를 해야 하는 시나리오 (파일 송신 등)에서, 사용자 수가 증가하는 경우 할당할 수 있는 thread가 없어, 동시 접속이 늘어나는 경우 문제가 발생할 수 있을 것으로 판단됩니다. 이런 경우 어떻게 설계를 하는 것이 타당한지 의견을 구하고자 합니다.감사합니다.
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
IOCP의 WSAOVERLAPPED 구조체 상속에 관해서..
안녕하세요 IOCP 관련 자료를 찾아보던 중 WSARecv/WSASend 할 때 넣어주는 WSAOVERLAPPED 구조체를 상속한 사용자 구조체를 넘겨주는 경우를 봤습니다. 이렇게도 사용이 가능하다면 WSAOVERLAPPED 를 상속받았으니 호환 될 것이고 추가적인 데이터도 담을 수 있어 도움이 되겠다는 생각입니다.하나 궁금한 것이 있는데요 IOCP를 이용해서 넘긴 WSABUFF의 메모리영역은 커널에 의해 보호 받는다고 알고 있습니다. 마찬가지로 WSAOVERLAPPED 구조체도 커널에 의해 메모리 관리가 되는지 만약 관리가 된다면 상속을 통해 추가적으로 들어가는 정보도 관리에 포함이 되는지 궁금합니다감사합니다~
-
해결됨Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
메일 질문있습니다
5/31 이벤트 유튜브 영상 (https://youtu.be/3rpEsV0vnB8) 보고서선생님께 메일 보냈었는데메일이 안 간건지보낸 메일 주소가 잘못된건지보낸 방식이 잘못된건지 답변을 못 받았습니다.어떤 메일 주소로 어떻게 캡쳐해서 보내드리면 될까요?