IT’s Ha

[C#] TCP 소켓 전송 본문

.NET/C#

[C#] TCP 소켓 전송

Deleloper Ha 2023. 2. 9. 19:04
728x90
반응형

안녕하세요.

실무 또는 연구(공부)를 하실 때 TCP 소켓 통신에 대하여 공유하려고 합니다.

먼저, 프로그램 간 통신을 하기 위해 통신을 해야 할 경우가 생깁니다.

전송 byte는 보통 Header, 내용, Tail 이렇게 통신을 구성합니다. (규약은 정하기 나름이기 때문에 항상 그런 건 아닙니다)

private readonly byte[] headFrame = {0x44, 0x55};
private readonly byte[] tailFrame = {0x77, 0x88};

저는 소스 코드에 해더와 테일을 선언을 하여 사용을 합니다.

1. 소켓 오픈

Socket mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
mSocket.ReceiveTimeout = 1000;		// 수신 Timeout 설정
mSocket.SendTimeout = 1000;			// 송신 Timeout 설정

var result = mSocket.BeginConnect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), Convert.ToInt32(50001)), null, null);
bool success = result.AsyncWaitHandle.WaitOne(1500, true);	//Timeout Check 1.5초 설정
if (success)
{
	// 정상 연결
	mSocket.EndConnect(result);
}
else
{
	// Connection Timeout 발생
	mSocket.Close();
	mSocket.Dispose();
}

- 소켓을 생성합니다. 그리고 송/수신 Timeout 설정하였습니다.(1초)

- Connect 함수를 사용하여 연결이 가능하지만, 오랜 시간 대기 할 경우 시스템에 영향을 생각하여, Timeout 설정을 하였습니다. 

2. Send Byte 생성

private byte[] MakeByte(string command, params string[] param)
{
            byte[] byteData = new byte[2048];
            string _tmp = string.Empty;
            try
            {
                byteData[0] = headFrame;
                // 샘플 소스에서는 명령어와 변수를 전달
                // 명령여;변수1,변수2,
                _tmp = command + ";";
                for (int i = 0; i < param.Length; i++)
                {
                    _tmp += param[i];
                    if (i != param.Length - 1)
                        _tmp += ",";
                }
                
                byte[] tmpb = Encoding.ASCII.GetBytes(_tmp);
                // byte배열로 변환
                for (int i = 1; i <= tmpb.Length; i++)
                {
                    byteData[i] = tmpb[i - 1];
                }
                // byteData에 데이터 넣기
                byteData[tmpb.Length + 1] = tailFrame[0];
                byteData[tmpb.Length + 2] = tailFrame[1];

                return byteData;
            }
            catch (Exception ex)
            {
                return null;
            }
 }

- 전송해야 할 데이터를 byte로 변환

3. 전송 및 수신

if (!mSocket.Connected)
	return;
mSocket.Send(sendData);
mSocket.Receive(readData);

- 소켓이 연결되어있지 않다면, 처리되지 않고 return 된다. 그리고 아니면 데이터를 전송하고, 받은 데이터는 readData에 저장합니다.

4. 결과 값

rivate string[] ResultData(byte[] readData)
{
            string[] resultData;
            try
            {
                resultData = new string[readData.Length];
                byte[] tmp = new byte[readData.Length - (headFrame.Length-1)];
				// 헤더는 제외 하고 받기
                int cnt = 0;
                for (int i = 0; i < tmp.Length; i++)
                {
                	// 뒤에 값이 테일 프레임값이랑 같으면 종료
                    if (readData[i + 1] == tailFrame[0] && readData[i + 2] == tailFrame[1])
                    {
                        cnt = i;
                        break;
                    }
                }
                // 해당 결과값까지만 저장
                tmp = new byte[cnt];
                for (int i = 0; i < cnt; i++)
                {
                    tmp[i] = readData[i + 1];
                }
                //ASCII로 변환
                string result = Encoding.ASCII.GetString(tmp);
                //결과값 테스트;1
                //문자열로 저장 반환
                resultData = result.Split(';');
                return resultData;
            }
            catch (Exception ex)
            {
                return resultData;
            }
}

- Byte를 문자열로 정리하여 저장

감사합니다.

728x90
반응형

'.NET > C#' 카테고리의 다른 글

[C#] Byte Array 0값 제거, Byte Array에 값 추가  (0) 2023.03.23
[C#] Datetime 차이 구하기, Null 설정  (0) 2023.03.09
[C#] Echo Server(에코서버)  (0) 2023.02.07
Comments