유투브나 검색해 나온 소켓 통신 예제를 여러개를 보고 작성해서 허접하게 나마 장비와 통신을 하고 있습니다.
작성한 winform에 종속 되다 싶이 소켓통신을 작성하여 쓰고 있어 다른 프로젝트에 사용 어렵기에 소켓 통신을 분리하여 구현하고 싶습니다.
주변에 C#, 닷넷을 하는 개발자님없어 정보 얻기가 어려워 여쭤봅니다.
다른 개발자님들은 저와 같이 이런 날 코딩은 하지 않으실 것 같은데 보통 회사서 통신 클래스를 작성하시는지 아니면 오픈소스를 사용하여 사용하시는건지요?
카메라, Lidar 센서 등과 소켓 통신하려면 안정성을 염두고 써야 할 것 같은데 어떤 방식으로 통신 구현 하시는지도 궁금합니다.
Socket 클래스는 Linux, macOS 또는 Windows와의 네이티브 상호 운용성에 의존하여 제공되는 소켓 서비스의 관리 코드 버전입니다. 대부분의 경우 Socket 클래스 메서드는 단순히 데이터를 해당하는 네이티브 항목으로 마샬링하고 필요한 모든 보안 검사를 처리합니다.
이 클래스는 윈폼과 같은 특정 UI 프레임워크에 종속된 것이 아닙니다.
이를 다시 직접 구현한다함은 닷넷에서 해 놓은 작업을 수작업으로 다시 작성한다는 의미인데, 그럴 필요가 있을까요?
그걸 한다고 해도 품질이 닷넷의 구현보다 나을 거라는 보장도 없을 뿐더러, 시스템 소프트웨어가 아닌, 응용 소프트웨어(Application)에 특화된 닷넷(의 C#)을 효율적으로 사용한다고 보기 어려울 것 같습니다.
다만, 특정 도메인에서는 소켓으로 주고 받는 데이터에 정형성이 있을 수 있고, 그 정형성에 대한 추상화를 잘해 놓으면, 미래에는 사소한 디테일의 추가만으로 기존 코드를 그대로 사용할 수 있게 만들 수는 있습니다.
namespace MyDomain;
public enum MachineStatus { Unknown = 0, Starting, Started, Error }
public enum MachineType { // ... }
// ...
public abstract class Machine;
public class MachineOptions<TMachine> where TMachine : Machine { // ... }
// ...
그 정형성을 얼마나 잘 정제하느냐에 따라 추상화의 품질 - 재사용성은 달라질 것이고, 정제 능력은 곧 도메인 지식과 경험에 좌우될 것입니다.
내용으로는
event Connected
event Disconnected
Open();
Close();
Task WriteAsync
Task<~> ReadAsync
…
과 같이 정의 하구요.
시리얼통신 : RJCP.IO.Ports (기본 시스템.IO.시리얼포트는 ReadAsync에서 ct로 cancel 불가한 사항이 있어서 해당 라이브러리 사용)
TCP client : 기본 TCPClient 사용
…
등 통신 라이브러리를 위 I~Stream에 맞추고 (Disconnect 감지가 없다면 내부에서 자체적으로 polling을 추가로 구현 한다던지… 하여 구현 soket Poll 같은)
이제 통신이 필요한 상위 모듈 (계측기라던지… 카메라던지 등)은 IStream을 주입 받아서 write/read 등을 사용하구요
저는 소켓 통신을 하는 경우는 어떻게 보면 이미 특정케이스? 필요사항이라고 생각합니다. 그러니까 재사용성을 염두해두고 라이브러리화해서 쓰지 않고 그때그때 만들어 씁니다.
윈폼에 종속성인 부분은 위에 이슈와 별게라고 생각합니다. 소켓프로그래밍이 아니라 어떤 필요사항이라도 UI와 얼마나 분리하고 어떻게 분리하냐는 자기맘대로 아닐까요. UI 종속성은 좋은 상태는 아닐거구요. 저는 솔루션안에 라이브러리 프로젝트로 소켓통신 영역을 분리하는 경우는 거의 없었고 그냥 한 프로젝트 내에서 클래스로 분리합니당
날코딩…이라기보다 평소에 자주 쓰는 패턴으로 Socket 프로젝트를 별도로 만들어뒀어요.
그걸 통신이 필요할때 솔루션에 프로젝트 추가해서 씁니다.
그리고 이마저도 대부분의 경우, 컴파일해놓은 바이너리 dll을 참조해서 씁니다.
그 외에도 외부 라이브러리 사용이라는 선택지가 있겠으나, 보편적인 TCP Socket이 아닌 MQ와 같은 패킷형태라면 사용할 수가 없을거구요. (장비 프로토콜 호환X)
회사에서 사용하고 있는 (공식적인) 라이브러리가 있다면 그걸 쓰는게 가장 좋을것 같은데 여의치 않다면 비동기 패턴으로 socket 클래스 하나 만들어두시고 써먹으시는게 가장 좋을 것 같습니다.