목록c# (27)
Coding Memo
이 글은 해당 에러를 확인하면서, 정리한 글이다. 먼저 내가 사용했던 코드를 다시 한번 살펴보자.public IEnumerator PostCo(string url, T data, Action callback){ string json = Newtonsoft.Json.JsonConvert.SerializeObject(data); using (UnityWebRequest request = UnityWebRequest.Post(url, json)) { byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(json); request.uploadHandler = new UploadHandlerRaw(bodyRaw); req..
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..
Summary Web 상에서의 Http, Https를 이용한 req/res의 body의 text를 직렬화/역직렬화할 때, 타입에 유의하자. nullable 타입과 그렇지 않은 타입은 다르게 직렬화/역직렬화 된다. (예를 들어 int? 타입은 "null"값으로 파싱하지만, 단순 int 타입은 0(default) 값이 될 것이다.) nullable 타입은 아예 text로 `null`이라는 값으로 들어온다. 반드시 서버와 클라이언트에서 같은 데이터에 대한 클래스의 멤버 타입들은 특별한 이유가 없다면 동일하게 해주자.C# 8.0 부터 nullable 기능이 도입되었다. 이 Nullable Reference Types를 사용하면 null이 될 수 있는 참조형 변수와 될 수 없는 참조형 변수를 구분할 수 있다. 즉..
Summary 1. 소켓이 listening 상태에서 Accept를 하지 않고 backlog도 여유가 있을 경우에 클라이언트에서 이 소켓에 Connect를 하게 된다면 실제로 연결이 되지 않았지만(Accept 되지 않았지만) 클라이언트에서는 Connect에 성공한 것으로 간주될 수 있다. 따라서 이 때, connect에 관련한 IO callback이 호출될 수 있고, SocketError 값 또한, Success로 받아들인다. 위 상황에서 서버는 실제로 Accept를 한 상태가 아니기 때문에 서버에서는 Connected로 간주되지 않는다. (다시 말하자면, accept를 하지 않고 있기 때문에 backlog(대기열)에만 연결 시도한 소켓이 추가되었을뿐 서버는 이 상태를 연결상태로 받아들이질 않는다.) 2..
Visual Studio에는 실행을 하기위한 Application이 아닌 Class Library로 프로젝트를 빌드를 했을 때 유용한 기능이 있다. (C# 뿐만 아니라 다른 언어에 대해서도 지원한다.) 라이브러리 프로젝트에 담긴 형식에 맞는 주석(xml 형식)을 빌드한 라이브러리 파일을 가져다 사용하는 프로젝트에서도 동일하게 확인할 수 있다. 위 이미지는 라이브러리 프로젝트에서의 코드이다. summary를 작성하고 마우스를 클래스에 올려다 두면 해당 설명이 표시가 된다! (흔히 코드를 작성할 때, 미리 컴파일되어 있는 파일에 있는 프로퍼티나 함수에 대한 설명이 나오는 것이 바로 이런 것이다.) 위와 같은 기능을 컴파일된 라이브러리를 사용하는 다른 프로젝트에서도 동일하게 사용할 수 있다! 먼저 간단하게 주..
서버와 클라이언트 사이에 패킷을 암호화 하여 전송을 하려고 계획했다. 생각한 2가지 방법은 일단 모두 대칭키 방식이다. 첫 번째는 단순히 바이트 배열에 대한 비트연산을 활용하는 방법, 두 번째는 AES 암호화를 사용하는 방법. 간단한 비트 연산 xor 연산을 이용하여 암호화 및 복호화하는 방법이다. public byte[] Encrypt(byte[] data, byte[] key) { byte[] encrypted = new byte[data.Length]; for (int i = 0; i < data.Length; i++) { encrypted[i] = (byte)(data[i] ^ key[i % key.Length]); } return encrypted; } public byte[] Decrypt(b..
BitConverter는 .NET에서 제공하는 API로 기본 primitive 타입들의 데이터를 바이트 배열(byte[])로 직렬화하거나 바이트 배열을 역직렬화하는 기능을 제공한다. 제공되는 Primitive Types - Boolean - Char - Double - Int16 (short) - Int32 (int) - int64 (long) - Single (float) - UInt16 (ushort) - UInt32 (uint) - UInt64 (ulong) Note: float형이 Single로 된다는 것을 유의하자. 아래 문서에 자세히 나와 있다. https://learn.microsoft.com/ko-kr/dotnet/api/system.bitconverter?view=net-8.0 BitCo..
C#에서 어떤 타이머를 구현하거나 실행 예약 등을 할 때 Environment.TickCount를 이용할 수 있다. (물론 타이머는 기본적으로 제공하기는 한다. (System.Timers.Timer 등)) https://learn.microsoft.com/en-us/dotnet/api/system.environment.tickcount?view=net-8.0 Environment.TickCount Property (System) Gets the number of milliseconds elapsed since the system started. learn.microsoft.com 기계어로 번역되어 있는 부분이 많이 보이는데 항상 이해을 하지 못할 정도로 제대로 번역이 되어 있지 않은 경우가 많은 것 같다..