Carambolas는 여러 .NET 표준 2.0 어셈블리로 구성된 진화하는 범용 지원 라이브러리입니다. 특히, 소프트 실시간 제약 조건을 갖춘 낮은 대기 시간/저 대역폭 지정 제품 네트워크 응용 프로그램을위한 맞춤형 멀티 채널 신뢰할 수있는 UDP 프로토콜 구현을 특징으로합니다. .
첫 번째 릴리스는 완전히 기능적인 네트워크 모듈이있는 최소한의 코어입니다. 이 저장소는 향후 새 모듈을 추가하여 확장 할 계획이므로 단일 솔루션 주위로 구성됩니다.
테스트 범위는 여전히 최소화되므로 소스 코드를 면밀히 검사하지 않고는 정확성 수준을 암시해서는 안됩니다. 이것은 초기 단계의 진행중인 프로젝트입니다.
바이너리는 곧 아카이브 섹션 또는 NUGET 패키지 형태로 제공 될 예정입니다.
로컬 호스트 는 carambolas.net.host 의 인스턴스로 표시됩니다. 원격 호스트에 연결하거나 들어오는 연결을 수락하는 데 사용해야합니다.
모든 원격 호스트는 carambolas.net.peer 인스턴스로 표시됩니다.
연결, 단절 및 데이터와 같은 이벤트는 호스트 객체를 통해 수신되며 피어 객체는 데이터를 보내거나 적극적으로 연결을 끊는 데 사용될 수 있습니다.
이 시점에서 연결, 분리, 송신 및 수신 작업은 차단이 없습니다. 개방적이고 가까운 것은 차단되고 있습니다 (명백한 이유로).
동일한 호스트 오브젝트는 연결을 적극적으로 요청하고 들어오는 연결을 동일하게 수락하여 P2P 토폴로지에서 사용할 수있게하는 데 사용될 수 있습니다. 클라이언트/서버 역할은 호스트 구성 방식에 의해 단순히 시행되지 않으며 나타납니다. 호스트는 연결 요청을 여러 원격 호스트에게 동시에 보낼 수도 있습니다.
예 :
원격 피어에 연결하도록 인스턴스화 된 호스트 객체. 내부 루프는 이벤트가 다음 반복에 축적되지 않도록하는 책임이 있습니다.
using ( var host = new Host ( "MyHost" )
{
host . Open ( IPEndPoint . Any , new Host . Settings ( 0 ) ) ;
host . Connect ( new IPEndPoint ( IPAddress . Loopback , 1313 ) , out Peer peer ) ;
.. .
while ( true )
{
while ( host . TryGetEvent ( out Event e ) )
{
if ( e . EventType == EventType . Data )
Console . WriteLine ( $ "DATA: { e . Peer } { e . Data } " ) ;
else if ( e . EventType == EventType . Connection )
Console . WriteLine ( $ "CONNECTED: { e . Peer } " ) ;
else if ( e . EventType == EventType . Disconnection )
{
Console . WriteLine ( $ "DISCONNECTED: { e . Peer } { e . Reason } " ) ;
return ;
}
}
Thread . Sleep ( 33 ) ;
}
}호스트 객체는 최대 10 개의 들어오는 연결을 기다리기 위해 인스턴스화되었습니다. 내부 루프는 이벤트가 다음 반복에 축적되지 않도록하는 책임이 있습니다.
using ( var host = new Host ( "MyHost" )
{
host . Open ( new IPEndPoint ( IPAddress . Loopback , 1313 ) , new Host . Settings ( 10 ) ) ;
.. .
while ( true )
{
while ( host . TryGetEvent ( out Event e ) )
{
if ( e . EventType == EventType . Data )
Console . WriteLine ( $ "DATA: { e . Peer } { e . Data } " ) ;
else if ( e . EventType == EventType . Connection )
Console . WriteLine ( $ "CONNECTED: { e . Peer } " ) ;
else if ( e . EventType == EventType . Disconnection )
{
Console . WriteLine ( $ "DISCONNECTED: { e . Peer } { e . Reason } " ) ;
return ;
}
}
Thread . Sleep ( 33 ) ;
}
} 이 프로젝트는 토론토 영화 학교에서 비디오 게임 디자인 및 개발을 공부하기 위해 캐나다에 왔을 때 2015 년으로 거슬러 올라갑니다. 원래 동기는 여러 Unity3D 프로젝트에서 재사용 할 수있는 액세서리 클래스의 편집을 만드는 것이 었습니다. 잠시 후, 나는 Prospect 멀티 플레이어 게임을위한 네트워크 솔루션을 조사하기 시작했고 재사용 가능한 네트워크 모듈을 설계하는 데 중점을 두었습니다. 처음에는 UNET 또는 당시 찾을 수있는 다른 적절한 제 3 자 도서관을 통합하는 간단한 문제로 문제에 접근했습니다. 얼마 지나지 않아 나는 깨진 가정에서 숨겨진 구현 트레이드 오프에 이르기까지 모든 종류의 문제에 부딪 치기 시작했습니다. 팽창 된 (거의 오해의 소지가있는) 기능 목록, 디자인 비 호환성 또는 평범한 구현을 찾는 것은 드문 일이 아닙니다. 특히, 저를 가장 괴롭히는 것은 솔루션의 많은 측면이 왜 그 접근법이 선호되는지 또는 특정 한계가 부과 된 이유에 대한 설명으로 무작위로 임의적 인 것처럼 보였다. 나는 프로젝트의 소스를 검사하여 코드의 또 다른 부분이 직접 모순된다는 것을 알기위한 이유를 알아 내기 위해 프로젝트의 소스를 검사 할 수 있습니다.
이 모든 것이 저를 더 많은 작업으로 이끌었고 결국 나는 구현하고 확인할 수있는 합리적인 기능 목록으로 가벼운 네트워크 라이브러리를 직접 구축하기로 결정했습니다. 서두르지 않고 마감일도 없습니다. 내가 고안 할 수있는 최상의 기술 솔루션을 구현하려는 진정한 시도.
한편, 나는 졸업하고 풀 타임으로 돌아가서이 프로젝트를 제쳐두어야했다. 1 년 전, 오래된 노트를 찾은 후, 나는 프로토 타입의 아카이브를 복원하고 수집 한 모든 정보와 함께 포괄적 인 빌드를 구성하기로 결정하여 다른 사람들뿐만 아니라 그것이 작동하는 방식과 그 이유를 이해할 수있었습니다.
관리되는 어셈블리는 C# 7.3 이상을 지원하는 컴파일러가있는 모든 플랫폼에 구축 할 수 있습니다. 테스트 및 액세서리 응용 프로그램에는 Netcore 2.2가 필요합니다.
기본 라이브러리는 GCC 또는 Visual Studio와 함께 CMAKE를 사용하여 구축 할 수 있습니다.
지원되는 OS 버전 :
다른 플랫폼 또는 필요한 기본 라이브러리가없는 경우, 폴백 코드는 일반적으로 덜 효율적 일 수 있지만 완전히 기능하고 투명해야한다는 것이 존재합니다.
모든 C# 프로젝트 및 빌드 스크립트는 프로젝트 루트에있는 빌드 폴더 아래에 중간 파일과 바이너리를 저장하도록 구성되어 있으므로 빌드를 쉽게 검사, 검증 및 청소할 수 있습니다.
이 코드는 dllimport를 사용하여 기본 라이브러리를 바인딩합니다. Dllimport는 항상 Windows 라이브러리 이름을 사용할 수 있으며 필요에 따라 다른 플랫폼의 접두사/접미사를 자동으로 추가합니다. 예를 들어, Windows의 NET Native Library의 이름 인 Carambolas.net.native.dll은 linux 및 linux 및 libcarambolas.net.native.dll.dynlib에서 libcarambolas.net.native.dll.so가됩니다. 빌드 스크립트는 이미 적절한 이름으로 라이브러리를 생성합니다.
편의를 위해 Visual Studio 솔루션이 포함되어 있으므로 Windows에는 추가 빌드 단계가 필요하지 않습니다. 호스트 운영 체제 (X86 또는 X64)에 해당하는 플랫폼 만 선택하십시오. 테스트 응용 프로그램을 구축하고 단위 테스트에 필요합니다. 모든 .NET 어셈블리는 선택한 솔루션 플랫폼에 관계없이 ANDYCPU 용으로 제작되었지만 Visual Studio는 관련 어셈블리와 함께 나란히 배포 될 것으로 예상되는 테스트를 위해 구축 할 기본 라이브러리를 알아야합니다.
Nugetpack.bat을 사용하여 기본 라이브러리 및 휴대용 어셈블리를 컴파일하고 단일 작업으로 Nuget 패키지를 만듭니다.
Build.Bat을 사용하여 Visual Studio를 사용하지 않고 출시를위한 모든 프로젝트를 구축하십시오.
MAC 용 Visual Studio는 테스트되지 않았으며 지원되지 않으므로 작동하지 않을 것입니다.
기본 라이브러리를 컴파일하려면 Cmake (> = 2.8) 및 GCC를 갖추어야합니다. Dotnet Core SDK 2.1은 어셈블리를 컴파일하고 NUGET 패키지를 생성하려면 필요합니다.
Nugetpack.sh를 사용하여 기본 라이브러리 및 휴대용 어셈블리를 컴파일하고 단일 작업으로 Nuget 패키지를 만듭니다.
Build.sh를 사용하여 Visual Studio를 사용하지 않고 출시를위한 모든 프로젝트를 구축하십시오.
X86 및 X64의 기본 라이브러리를 컴파일 할 수 있도록 CMAKE (> = 2.8), 빌드 필수 및 GCC-Multilib가 설치되어 있는지 확인하십시오.
Ubuntu Run에서 : $ sudo apt-get 설치 빌드 필수 GCC-Multilib G ++-Multilib Cmake
Dotnet Core SDK 2.1은 어셈블리를 컴파일하고 NUGET 패키지를 생성하려면 필요합니다.
우분투 달리기 :
$ wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
$ sudo dpkg -i packages-microsoft-prod.deb
$ sudo apt-get update;
sudo apt-get install -y apt-transport-https &&
sudo apt-get update &&
sudo apt-get install -y dotnet-sdk-2.1
Nugetpack.sh를 사용하여 기본 라이브러리 및 휴대용 어셈블리를 컴파일하고 단일 작업으로 Nuget 패키지를 만듭니다.
Build.sh를 사용하여 Visual Studio를 사용하지 않고 출시를위한 모든 프로젝트를 구축하십시오.
XUNIT 프로젝트를 사용하여 주요 기능을 중심으로 최소 단위 테스트 세트가 구현됩니다.
carambolas.net.tests.host는 기본 네트워크 기능을 수동으로 확인하는 데 사용되는 간단한 콘솔 응용 프로그램입니다. Wireshark와 Clumsy와 함께면 특히 유용합니다
carambolas.net.tests.integration은 xunit과 함께 구현 된 Carambolas.net의 통합 테스트 세트입니다. 테스트는 각각 특정 시간 동안 루프백 인터페이스를 통해 통신하는 두 개의 개별 스레드 (서버 및 클라이언트)를 시작합니다. 루프백은 왕복 시간이 최소 인 이상적인 네트워크를 나타냅니다. 패킷은 순서대로 도착하지 않으며 뷔퍼 오버플로가 없다면 절대 손실되지 않습니다. 이러한 특성은 일반 실행 경로를 검증하는 데 유용합니다.
Wireshark는 네트워크 활동을 모니터링하고 패킷을 검사하는 데 사용할 수있는 귀중한 디버깅 도구입니다. 또한 Wireshark는 사용자 정의 프로토콜을 분석하는 데 사용할 수있는 해부자라는 특수 클래스 플러그인을 지원합니다.
이 프로젝트에는 Carambolas의 기본 Wireshark Dissector가 포함되어 있습니다. 이를 사용하려면 Wireshark가 이미 설치되어 있는지 확인하십시오.
Clumsy는 사용자 모드에서 실행되며 패킷을 가로 채서 실시간으로 저하 된 네트워크 조건을 시뮬레이션 할 수있는 네트워크 패킷 캡처 프로그램입니다.
config.txt 파일의 다음과 같은 사전 설정 필터 라인을 추가하여 통합 테스트에 사용 된 동일한 포트에서 루프백 인터페이스에 연결된 호스트에 영향을 미칩니다 (1313).
carambolas: udp and outbound and loopback and (udp.DstPort == 1313 or udp.SrcPort == 1313)
루프백 인터페이스와 함께 Clumsy를 사용할 때 몇 가지 경고가 있습니다. 서투른 사용자 매뉴얼 :
- 루프백 인바운드 패킷은 캡처하거나 다시 주입 할 수 없습니다. 당신이 그것에 대해 생각할 때, 컴퓨터에서 패킷을 보낼 때 인바운드 또는 아웃 바운드 패킷이라고 말하기는 정말 어렵습니다. 실제로 기본 Windows 필터링 플랫폼은 모든 루프백 패킷을 아웃 바운드로 분류하는 것으로 보입니다. 기억해야 할 것은 루프백 패킷에서 처리 할 때 필터에 "인바운드"를 가질 수 없다는 것입니다. 라우터가 할당 된 인트라넷 IP와 같이 컴퓨터에 127.0.0.1 이외의 IP가있을 수 있음을 아는 것이 중요합니다. 이들은 또한 루프백 패킷으로 간주됩니다.
- 루프백 패킷은 두 번 캡처됩니다. 인바운드 루프백 패킷이 없으므로 모든 루프백 패킷은 아웃 바운드로 간주됩니다. 서투른 것은 두 번 처리 할 것입니다. 처음은 보낼 때와 두 번째로받을 때입니다. 간단한 예는 필터가 단순히 "아웃 바운드"이고 500ms의 지연을 적용한다는 것입니다. 로컬 호스트를 핑하면 1000ms의 지연이 될 것입니다. 대상 포트와 이와 같은 물건을 지정하여 작업을 수행 할 수 있습니다. 그러나 매개 변수를 설정할 때 이것을 명심하고주의를 기울이는 것이 더 쉬울 것입니다.
- 인바운드 패킷 캡처는 항상 작동하지 않습니다. 앞서 언급했듯이 루프백 인바운드 패킷은 다시 주입 할 수 없습니다. 문제는 경우에 따라 대상 IP가 컴퓨터가 아닌 경우에도 일부 패킷이 인바운드 패킷으로 분류 될 수 있다는 것입니다. 이것은 비 루백 패킷에만 영향을 미칩니다. LocalHost에서만 작업하고 있다면 괜찮을 것입니다. 향후 릴리스의 목표는이 원인을 진단하고 해결책을 제공하는 것입니다.
- 프로세스 시스템을 기반으로 필터를 필터링 할 수 없습니다. 넓은 네트워크 캡처는 기능으로 나열됩니다. 그러나 실제로 이것은 강력한 솔루션을 제공하는 쉬운 방법이 없기 때문입니다.
버그 보고서, 버그 수정 (더 나은!) 또는 개선 된 테스트 범위의 형태로 항상 기여에 열려 있습니다.
기능 요청은 환영하지만 얼마나 광범위하고, 실현 가능 또는 바람직한 지에 따라 백 로그에 보관할 수 있습니다. 기능 요청이 너무 복잡한 경우 전용 자원 (시간과 돈)이 제한되어 있기 때문에 스폰서 십에 따라 다를 수 있습니다.
이 프로젝트를 지원하려면 여러분의 의견에 관심이있을 수 있습니다.
포르투갈어에서 Carambolas는 복수 형태의 Carambola (= Starfruit)입니다. 이 용어는 또한 브라질의 특정 지역에서 구어체 적으로 사용되어 놀라움이나 조바심을 표현합니다.
Carambolas 이전에, 나는 사용 가능한 프로젝트에서 내 아이디어를 정리하려는 최소한 6 마리의 시도를했습니다. Carambolas를 사용하면 디자인 문제에 대해 배우고 다양한 접근 방식을 테스트하기 위해 일련의 프로토 타입을 구축하기로 결정했습니다. 각 프로토 타입에는 문자로 형성된 코드 이름과 A1에서 시작하는 숫자가있었습니다. 이 저장소에서 처음에 가져온 소스 코드는 9 번째 프로토 타입의 75 번째 반복이므로 A9입니다.
기본 라이브러리는 주로 성능의 이유로 제공되므로 완전히 선택 사항입니다. 가능한 모든 플랫폼 (모든 데스크탑, 모바일, 콘솔, 내장에 대해 생각해 보는 것)에 기본 구현을 제공하는 것은 불합리했으며, 기본 라이브러리에만 의존하면 대상 플랫폼을 소수의 데스크탑 만 (Windows, Linux 및 MacOS)로만 줄일 수 있습니다. 따라서 일반적으로 기본 라이브러리에서 구현 한 모든 기능에 대한 관리 코드에 항상 폴백 구현이 있어야합니다.
기본 라이브러리는 선택 사항이므로 프로그램은 누락 된 파일이 있는지 여부를 알 수 없으므로 누락 된 기본 라이브러리에 오류가 발생하거나 기록되지 않은 이유는 무엇입니까? 정의상, 누락 된 기본 라이브러리는 결코 오류가 아닙니다.
일반적으로, 당신은 할 수 없습니다. 그리고 당신은 적어도 API 관점에서 벗어나지 않아야합니다. 사용자 (또는 앱 프로그래머)는 부양 가족,이 경우 Carambolas에 의해 어떤 기본 구현 전략을 사용하는지는 중요하지 않아야합니다. 그러나이 정보는 배포와 관련이있을 수 있으므로 자동 폴백이있는 Interop 객체를 만들 때마다 코드는 표시 로그 정보를 생성합니다. 예를 들어, Carambolas.net.socket은 기본 소켓 구현에 기본 라이브러리가 발견 될 때 "Carambolas.net.sockets.native.socket 사용"과 유사한 로그 정보를 생성합니다. 이 방법으로 기본 라이브러리를 염두에두고 배포하는 경우 실제로 사용되는지 여부를 결정할 수 있습니다.
즉, 잘못된 CPU 아키텍처를 위해 손상되거나 컴파일 된 기본 라이브러리를 배포한다는 것을 의미합니다.
기본 라이브러리는 해당 인터롭 어셈블리와 나란히 진행해야하며, 어셈블리는 모든 CPU 아키텍처에 대해 한 번 컴파일 될 수 있지만 기본 라이브러리는 할 수 없습니다. 실행중인 운영 체제의 CPU 아키텍처와 일치해야합니다. 그렇지 않으면 손상된 파일로 취급되고 .NET는 시스템을 던졌습니다 .BadimageFormateXception. 이것은 정의에 따라 오류가 아닌 라이브러리를로드하려고하는 것과 동일하지 않습니다.
BDP (Bandwidth-Delay 제품)는 네트워크 링크의 전송 용량 (초당 비트) 및 왕복 지연 시간 (초)의 제품입니다. 이는 승인이 도착하기 전에 네트워크가 유지할 수있는 최대의 데이터 양을 나타냅니다.
BDP는 네트워크가 특정 임계 값 이상인지 여부에 따라 네트워크를 분류하는 데 사용될 수 있습니다. 큰 BDP를 가진 네트워크를 LFN (Long Fat Networks)이라고합니다. LFN은 평균 왕복 시간 (위성 링크에서와 같이 대역폭이없는) 또는 넓은 (높은 대역폭) 네트워크가있는 네트워크 일 수 있으며 (기가비트 이더넷 링크에서와 같이) 상당히 작은 왕복 시간을 표시합니다.
자세한 내용은 Wikipedia를 확인하십시오.
Carammbolas.net.socket 객체는 기본 소켓 구현 또는 System.net.sockets.socket에 의존하는 폴백 구현의 외관 역할을합니다. 호스트 및 피어 객체의 복잡성을 분리하고 줄이는 데 도움이됩니다. 자세한 내용은 doc/readme-carambolas.net을 참조하십시오.
System.net.ipaddress 및 System.net.pendpoint는 .NET Core 및 .NET Framework의 모든 현재 구현에서 불필요한 할당을 촉진하는 Mutable 객체입니다. carambolas.net.ipaddress 및 carambolas.net.ipendpoint는 GC 압력을 줄이는 데 기여하는 불변의 가치 유형입니다. 자세한 내용은 doc/readme-carambolas.net을 참조하십시오.
Chacha20 및 Poly1305를 갖는 AEAD는 기본적으로 지원됩니다. CARAMBOLAS.NET.net.nickher 및 Carambolas.net.ickherFactory 인터페이스의 구현을 호스트에게 제공함으로써 사용자 정의 전략을 구현할 수 있습니다. 유일한 요구 사항은 다음과 같습니다.
사용자 애플리케이션은 전송하기 전에 데이터를 자유롭게 압축 할 수 있지만 현재 개별 메시지 또는 완전한 패킷의 자동 압축/감압을 제공하는 메커니즘은 없습니다.
사용자 애플리케이션과 함께 배포되도록 생성 된 모든 소스 코드 및 이진은 MIT 라이센스에 따라 라이센스가 부여됩니다.
Carambolas.commandlinearguments는 Griffonrl의 기사를 기반으로 MIT 라이센스 아래에 소스 코드가 게시 된 Jake Ginnivan의 다른 기사의 추가 아이디어와 함께 원래 소스에서 확장되었습니다.
Carambolas.security.criptography.crc32c는 MIT 라이센스에 따라 강제로 CRC32.Net을 기반으로합니다.
Carambolas.security.criptography.naCl은 MIT 라이센스에 따라 David de Smet에 의해 NaCl.core에 기반을두고 확장되었습니다.
Wireshark에 대해 LUA로 작성된 프로토콜 디스렉트는 GPLV3 라이센스에 따라 제공됩니다. 기능을 확장하고 Carambolas 네트워크 프로토콜에 따라 형식화 된 UDP 패킷에 대한 자세한 정보를 표시하기 위해 Wireshark의 입력 파일로만 사용해야합니다. 따라서 완전히 분리되어 있으며 소스 파일, 어셈블리 또는 기본 라이브러리와 상호 작용, 의존 또는 기여하지 않습니다.