[C#] TCP 통신 뜯어보기 1탄
다들 많이 찾아볼 거다 IoT 관련 업종이나 FA(공장자동화) 쪽에서는
통신이 무척이나 중요하기 때문이다.
이번 시간에는 순수하게 C#에서 제공하는 라이브러리만 사용해서 만들어보자
확인해볼 사항
1. 재 연결 interval을 얼마로 둘것인가?
2. 끊어진지 어떻게 확인할 것인가?
3. 마냥 기다릴 수 만은 없기 때문에 몇 초 정도 후 데이터 미 송신시 재 연결을 진행할 것인가?
4. 메모리 누수가 안 생기면서 서버에 들어오는 모든 요청을 답할 수 있을 것인가?
5. Ack 값이 한번에 전부 수신이 안될경우 몇 초정도 딜레이를 두고 대기할 것인가.?
등등...
정말 완벽한 메모리의 누수가 없는 통신이 가능하면서 데이터를 송수신 할 떄
다 처리할 수 있을 것인가?
프로그램을 항상 개발할 때 드는 생각이다...
서론이 너무 길었고 어쨌든 서론의 포인트는
완벽한 통신은 고민과 경험에서 나온다.
이제 코딩을 해보자
최근에 깨닫게 된 걸 먼저 상기하고 만들려고 한다.
이 글을 보기 전에 2가지만 확인하자!
1. 코드의 재사용성
2. 무조건 비동기가 좋은건 아니기에 구분해서 사용하자
1. enum을 사용해서 클래스의 인스턴에 구분을 두자
public enum FuctionTCP
{
[Description("SERVER CREATE")]
SERVER = 0,
[Description("CLIENT CREATE")]
CLIENT = 1
}
위와 같이 구분을 둘 경우에는 열거형 자료를 사용해서 구분하는게 좋다(내 기준... )
그래서 클래스 생성자에서 구분해서 받도록 구성해보자
public tcpHelper(FuctionTCP brDistinguish)
{
switch (brDistinguish)
{
case FuctionTCP.SERVER:
_servers = new List<tcpClients>();
_listener = new TcpListener(System.Net.IPAddress.Any, 5000);
_listener.Start();
//프로그램 종료 시에 같이 종료하기 위한 값
_programRunning = true;
break;
case FuctionTCP.CLIENT:
_clients = new TcpClient();
_clients.connect();
initConnect(_clients);
break;
default:
break;
}
}
public async void initConnect(TcpClient tempCli)
{
Netstream tempNS = tempCli.GetStream();
//여기선 값을 수신만 한다.
//...
//Netstream 관련 부분을 공부하면 관련 함수를 사용해서
//더 코드를 가용성있게 사용할 수 있다.
}
이렇게 되면 해당 클래스를 선언만 해도 별도의 구문 없이 자동으로 연결 시도와 서버가 열려진다.
물론 재 연결 파트를 위해서 connect 함수를 별도로 빼놓은 거다
Timer _timer;
public void connectTry()
{
//C#에서 제공하는 connected는
//해당 소켓이 연결된 적이 있으면 연결되어 있지 않아도 true를 반환한다.
//그래서 별도의 구분 값이 필요하다.
if(!isConnect)
{
try
{
//비동기를 사용하지 않은 이유는
//타이머 자체가 스레드임
_clients.connect();
isConnect = true;
}
catch()
{
isConnect =false;
//연결을 실패할 경우 실행할 로직 추가
//...
}
}
}
( 변수의 대소문자 구분이 안되는 경우는 양해 .... 부탁)....

물론 코드 자체가 원래 창작성이 있어서 다 같을 수는 없어서
환경에 따라서 자기가 알아서 쓰면 됨 ㅎㅎ
마지막으로 적어놓을 말은
개인적으로 제일 생각없이 짠 코드는 응답값 확인도
없이 임의로 끊는 코드인거 같다.(딜레이는 좀 길게 주자.... 재송신 코드도 필요)