목록분류 전체보기 (162)
Coding Memo
3가지 직렬화를 비교해보자. 1. BitConverter를 이용2. Unsafe 코드인 StructureToPtr을 이용하여 메모리 내용을 그대로 이용3. 직접 바이트를 조작속도 비교 C++로 작성된 서버와 C#으로 작성된 클라이언트의 통신에서 패킷 정보 파싱을 위해 PacketHeader라는 구조체를 이용했다. PacketHeader는 unsigned int16 (ushort)의 Id 값과 같은 타입의 Size로 이루어져 있다. C++의 placement new를 이용해서 메모리에 있는 값 그대로 전송하여 C#에서 파싱하는 형태이다. PacketHeader는 다음의 구조이다.[Size, 2 bytes][Id, 2 bytes] C#에서도 위 메모리 순서를 지키면서 다음 구조체를 작성하였다.[StructL..
문제 소켓이 연결이 되었음에도 불구하고, getpeername() 함수가 SOCKET_ERROR를 반환하고, WSAGetLastError() 값이 10057(WSAENOTCONN)이었다. 해당 소켓에 대해 WSASend 및 WSARecv는 정상적으로 작동하였고, getsockname또한 정상적으로 작동하였다. 해결 연결된 소켓에 대해 SO_UPDATE_CONNECT_CONTEXT 옵션을 설정해 주면 된다.이후 getpeername은 정상적으로 작동하고, remote endpoint의 주소와 포트 번호를 가져올 수 있다. 설명 SO_UPDATE_CONNECT_CONTEXT는 소켓이 연결 된 이후에, 소켓의 속성을 업데이트하는 옵션이다. 이 옵션은 ConnectEx, WSAConnectByList, WSA..
윈도우에서 지원하는 concurrent에 대한 자료구조 헤더가 있는데, 이들은 lock-free로 구현되어 있으니 이 쪽을 사용하는 것이 훨씬 더 도움이 될 수도 있겠다 ㅋㅋ std::mutex를 이용한 lock과 std::priority_queue를 사용하여 간단한 concurrent 우선순위 큐를 만들어보았다.기본적인 push 및 pop 외에, 지정된 조건에 따라 결과값을 반환하는 TryPop등의 함수도 포함했다.상황에 따라 필요할 수도 있기 때문이다. (예를 들어, top의 객체를 확인하고 이 객체가 어떤 조건이 맞을 경우에만 pop을 해야할 필요가 있을 때, top과 pop을 따로하면 atomic하게 실행시켜야되는 데, 이 과정에서 외부 lock을 걸어야 되기 때문이다.) 추가적으로, 이동연산자를..
Summaryconst로 선언된 포인터는 포인터 값 뿐만 아니라, 해당 포인터가 가리키는 데이터의 변경도 막는다. 따라서 const 변수와 마찬가지로, const 포인터는 const가 아닌 값으로 캐스팅 할 수 없다. const로 선언된 포인터는 해당 포인터가 가리키는 데이터의 변경을 막는다. 만약, const 포인터가 가리키는 값을 변경할 필요가 있는 경우, `const_cast`를 사용하여 const 속성을 없애주면 된다.다음은 예시 코드이다.using uint = unsigned int;using ubyte = unsigned char;uint t = 0xffffffff;std::cout someInt(4, 0xFF); // it represents max of unsigned int { uby..
ReadWriteLock의 특징은 다음과 같다.1. Spinlock으로 구현2. unsigned int 값의 flag를 하나 지정하여, 상위 2바이트는 write중인 thread_id, 하위 2바이트는 현재 read중인 스레드의 수를 나타냄3. thread_id는 thread가 새로 시작할 때 id 부여4. write 중일 때는 다른 스레드들이 이 lock을 얻지 못함5. wrtie 중이 아닐 때는 다수의 스레드가 동시에 read 가능6. EMPTY_FLAG (어느 스레드도 lock을 가지고 있지 않을 경우)는 0x00000000 서버-클라이언트의 연결에서 가끔씩 패킷을 전송 할 때, 세션의 전송 함수 내의 WRITE_LOCK에서 spin-timeout이 나타났다. 즉, deadlock이다. 이번 문제의..
일단은 해당 내용은 에러나 경고로 나타나지 않고, 단순히 output에서 나타난 일종의 메시지 이다.the template instantiation context (the oldest one first) is 1> ...Session.cpp(49,23): 1> see reference to function template instantiation 'std::shared_ptr NetCore::make_shared,NetCore::_ubyte*&,const size_t&>(std::shared_ptr &&,NetCore::_ubyte *&,const size_t &)' being compiled 1> with 1> [ 1> _Ty=NetCore::Send..
상황 GetQueuedCompletionStatus()가 성공적으로 완료되었음에도 불구하고, Overlapped 구조체의 값이 이상했다. (기대했던 값이 아니었다.) GetQueuedCompletionStatus를 호출한 HANDLE에 `connectEvent`라는 overlapped를 상속하는 구조체가 연결되어 있는 파일 핸들을 등록했다. 따라서 GetQueuedCompletionStatus가 성공적으로 완료되었다면, 인자로 넣어주었던 LPOVERLAPPED*가 이 connectEvent를 가리키는 포인터가 되어야 된다. 그러나 이 포인터는 메모리 오염이 일어난 듯 값이 이상했다. 먼저, IOCPEvent와 ConnectEvent는 다음과 같다.// EventType은 unsigned ..
에러 Lock을 이용한 Queue를 만들고 컴파일 중에 발생했다. 일단 에러 내용은 이러하다. 상황 단순히 보면 ReadLock이라는 함수의 인자가 일치하지 않아서 나타나는 문제로 보인다... bool TryPeek(T& top) const { ReadLock __r_lock(_lock); // 문제의 코드 if (_queue.empty()) return false; else { top = _queue.top(); return true; } } 문제가 되는 함수이다. 간단히 설명하면, queue에서 peek을 하기위해 readlock을 걸어두고 queue를 읽는다. class ReadLock { public: ReadLock(Lock& lock) : _lock(lock) { _lock.ReadLock()..