소켓에서 발생하는 이벤트 - 소켓에서 읽기와 쓰기(2/2)

  소켓으로부터 데이터의 읽기, 쓰기 작업은 데이터를 수신, 송신하는 동작입니다. 소켓의 특성에 따라 두 가지로 나눌 수 있는데, Blocking socket과 Non-Blocking socket 입니다. 어쩌면 Non-Blocking 소켓을 처음듣는 분이 계실지도 모르겠네요. 소켓 프로그래밍을 다룬다고 하면 Blocking 소켓을 의미하는 경우가 많습니다. 이제 두 가지 소켓 종류에 따라 읽기, 쓰기 작업의 구현이 어떻게 달라져야하는지 알아보겠습니다. Blocking 소켓 소켓에서 처리되기를 원하는 작업이 완료된 이후 함수가 반환되어 다음 작업이 수행됩니다. 예를 들어, 쓰기(send) 작업의 경우에 내가 전송하려는 데이터가 모두 전송되면 send() 함수가 리턴됩니다. Non-Blocking 소켓 소켓에서 현재 처리될 수 없는 작업이면 기다리지 않고 즉시 반환됩니다. 반환값에 따라 적절한 처리가 필요합니다. 읽기, 쓰기 함수의 동작을 구체적으로 알아보고 구현상 주의해야할 점에 대해서 적어보겠습니다. 1. 읽기작업(recv 함수) 수신 구현을 알아보기 전에 먼저 수신 버퍼의 존재를 이해 해야합니다. 앞의 블로그( 링크 )에서 설명한 Receive Buffer에 대한 설명을 가져왔습니다. ==== Receive Buffer: 원격으로부터 전송받은 데이터를 임시로 저장하는 공간입니다. 데이터를 수신하게 되면 임시로 이 공간에 저장합니다. 이 공간은 커널영역의 메모리입니다. 어플리케이션에서 소켓으로부터 읽기를 시도하면 이 버퍼로부터 데이터를 가져오는 동작을 수행합니다. (즉, 커널영역의 메모리 공간에서 유저모드의 메모리 공간으로 복사가 발생함) ==== Blocking Socket를 다룰 때,  recv() 함수의 동작은 아래와 같습니다. recv() 함수를 호출하는 시점에, (1)  Receive Buffer 에 수신된 데이터가 이미 있다면, 그 데이터를 가져온 후에 반환. (2)  Receive Buffer 가 비어있고 연결이...

런드리고 4년의 회고

기억이 흐릿해지기   전에   런드리고(의식주컴퍼니)에서 있었던 4년의 회고를 적고자 합니다. 저에게 런드리고는 처음으로 스타트업이라는 곳을 경험하게 해준 곳이고 4년   동안   정말 훌륭한 동료들과 즐겁고 열정적으로 근무한 회사입니다. 저와 함께한 회사의 모든 동료들에게 감사함을 전합니다. 1. 채용 회사에 조인할 당시에 개발자 수는 한자리 숫자였어요. 앱 개발자, FE 개발자, BE 개발자 분포로 기술 스택은 Android Kotlin, iOS Swift, Frontend PHP, Backend Java-Spring, & Golang. 그리고, Kafka, Redis. 스타트업에서 좋은 개발자 채용은 어렵습니다. 이유도 명확합니다. 채용을 열어도 회사가 외부에 알려지지 않아 지원자가 많지 않고, 지원자의 역량(물론, 이력 내용으로만 판단)도 회사의 인지도와 비례하였습니다. 초기 스타트업이 채용에서 많이 사용하는 방식으로 지인 찬스가 있습니다. 물론, 이 방식에 대해서 장단점을 논하는 글을 본 적이 있지만, 지인 찬스 채용의 단점은 극복해야 할 문제이지 이 문제 때문에 사용하지 못할 이유는 없습니다. 저는 이 방식으로 채용했습니다. 운이 좋았습니다. 제가 과거에 같이 근무했던 훌륭한 시니어 개발자분들이 여러 명 조인해주셨어요. 스타트업으로 이직을 결정하는 여러 요소가 있는데, 그중에 하나가 회사가 어떤 사업을 하고 있느냐일 것입니다. 런드리고는 세탁 사업을 하고 있고, 세탁의 수요는 지속적입니다. 이 의미는 세탁 사업을 하는 회사의 전망은 밝을 것이라는 기대입니다. 이런 기대를 기반으로, 세탁은 어떤 문제를 해결해야 하는지, 개발을 통해서 해결할 수 있는지을 도전할 수 있다면 이는 개발자가 그 회사에 조인하게 만드는 중요한 요소입니다. 이제 중요한 요소 하나는 충족되었다고 보겠습니다. 다음은 어떤 사람들과 어떻게 일하느냐가 중요한 요소인데, 이것은 일종의 평판 조회와 유사한 것이고, 과거에 직접적인 동료였으니 이는 ...

소켓에서 발생하는 이벤트 - 발생 감지의 기준 level trigger와 egde trigger(1/2)

이미지
TCP로 연결된 두 지점은 소켓을 통하여 데이터를 전송하고 수신합니다. 소켓의 내부를 조금 더 들여다보면 데이터 전송을 위한 임시 공간이 존재하는데, Read Buffer, Write Buffer 입니다. (1) Read Buffer : 원격으로부터 전송받은 데이터를 임시로 저장하는 공간입니다. 데이터를 수신하게 되면 임시로 이 공간에 저장합니다. 이 공간은 커널영역의 메모리입니다. 어플리케이션에서 소켓으로부터 읽기를 시도하면 이 버퍼로부터 데이터를 가져오는 동작을 수행합니다. (즉, 커널영역의 메모리 공간에서 유저모드의 메모리 공간으로 복사가 발생함) (2) Write Buffer : 원격으로 데이터를 전송하기 전에 임시로 이 버퍼에 저장합니다. (이 공간도 커널영역의 메모리 입니다.) 어플리케이션에서 데이터 전송(send)를 수행하면 실제로는 이 버퍼에 데이터 쓰기 작업을 진행합니다. 네트워크 스택은 이 버퍼의 데이터를 전송함으로써 실제로 데이터 전달이 수행되는 것입니다. 소켓에서 발생하는 이벤트를 정의하는 것은 이 두 버퍼의 상태 변화를 의미하는 것입니다. 예를 들어, 어플리케이션에서 데이터를 수신(Read) 동작을 수행하기 위해서는 Read Buffer에 수신된 데이터가 존재한다는 것을 의미합니다. 어플리케이션에서 데이터의 전송(send)이 가능하다는 것은 Write Buffer에 여유공간이 있어서 데이터 쓰기 작업이 가능하다는 것을 의미합니다. 즉, 읽기 가능(Readable) 한가 또는 쓰기 가능(Writable)한가를 판단하는데 있어서 무엇을 기준으로 판단할 것인지 정하는 것인데, 단순히 버퍼의 데이터의 존재 유무가 판단 기준뿐만 아니라, 버퍼 공간의 변경 시점도 연관 이 있습니다. 이 두가지지 기준이 level trigger, egde trigger 입니다. 두 트리커의 차이점은 소켓버퍼에 데이터가 있는 경우에 그것을 소켓 이벤트로 간주하는 기준입니다. 참고로 이벤트 감지에 사용되는 구현이 각 OS에 있습니다. MS 윈도우: IOCP  ...