통신 관련 프로그램을 작성할 때 테스트에 꼭 필요한 녀석이라 임시로 만들곤 했었는데 이번에 생각난김에 조금 정리한걸 블로그에 올려봅니다.
서버 실행 파일 다운로드 링크 - 다운로드
소스 코드 다운로드 링크 - 다운로드
(해당 다운로드 링크는 제 구글 드라이브에 공유된 파일이라 안전합니다.)
(콘솔 형태의 간단한 버전도 포스팅 되었습니다 - 이동하기)

일단 가볍게 윈폼 프로젝트를 만들어서 기본 레이아웃을 구성합니다.
레이아웃은 우선

서버를 구성할 아이피와 포트 번호를 입력 받을 부분과

서버 이벤트를 책임질 토글 스위치 부분, 마지막으로

서버 이벤트 로그와 결과 값을 표현할 로그 화면부로 구성해봤습니다. ^^
이제 핵심인 코드를 작성해 볼까요?
이번 코딩은 소켓 통신의 구성 요소들을 C#으로 표현하는 것과, 사용자로부터 입력 받고 로그를 표현하는 윈폼 프로그램의 메인 스레드, 서버를 운영 할 서버 스레드 간 분기와 동기화 부분에 중점을 두고 작성하였습니다.

그럼 주요 부분을 볼까요?

.NET에서 소켓 통신은 System.Net.Sockets에서 담당합니다.
스레딩도 함께 참조 했어요.

서버 구성에 필요한 변수들입니다.
TCP/IP 서버이니 Tcp리스너 하나 선언하고, 클라이언트로부터 받은 데이터를 담을 스트림 하나와 그 데이터를 변환시킬 byte 배열 하나도 필요합니다.
마지막으로 서버 운영을 담당할 스레드도 하나 만들었습니다.
그리고 서버의 안내말과 로그는

스트링 빌더를 하나 선언해서 길이 제한도 달고 해당 텍스트 박스에 이쁘게 보이도록 세팅합니다.
이제 뭔가를 로그창에 남기고 싶으면

요렇게 스트링 빌더를 세팅해주는 매서드를 호출시키면 됩니다. ^^
이러면 프로그램이 처음 실행되고 필요한 기본 세팅은 갖추어 졌네요.
이제 사용자가 서버 실행이나 종료를 위해 토글 스위치를 클릭했을 경우엔

요렇게 플레그 하나를 기준으로 서버 실행과 종료를 담당할 매서드를 만들고
서버를 실행할 매서드는

바로 서버 운영을 맡길 스레드를 시작 시키도록 합니다.

스레드는 서버 구성에 필요한 아이피와 포트 번호 정보를 가져와서 Tcp 리스너를 활성화 하고 필요한 로그와 세팅을 메인 스레드에 간섭하여 작성해줍니다.

그리고 해당 리스너에 클라이언트로부터 받은 데이터가 감지되면 바로 필요한 형태로 변환 시켜 로그창에 보이도록 하였습니다. ^^
이제 스레드나 리스너가 종료될때 까지 계속 서버는 실행되고 있겠죠.

서버를 종료 시킬 매서드는 우선 실행중인 리스너와 스트림의 잔여값 여부를 확인하고, Tcp 리스너와 해당 스레드를 종료시킴으로 서버 종료를 유도합니다.
좀 더 정밀한 작동을 원한다면 약간의 딜레이를 주고 확인하는 로직을 두면 될꺼 같네요.
서버가 종료되면 필요한 정보를 다시 로그 창에 작성시킴으로 매서드는 종료됩니다.

마지막 부분은 로그 창을 깨끗하게 정리해줄 버튼 이벤트와 데이터 변환에 필요한 매서드입니다.
Tcp 서버와는 상관 없는 부분이라서 아래로 빼두었습니다. ^^
이제 프로그램을 실행하면

요렇게 나오며

서버 오픈 클로즈 이벤트 잘 실행되고 로그도 이쁘게 찍히네요. ^^
Clear 버튼으로 로그 삭제도 무난이 작동합니다.

요녀석은 TCP/IP 프로토콜을 사용하는 클라이언트 프로그램인데요.
텍스트 파일을 읽어서 해당 내용을 서버에 전송하도록 만들었습니다.

요렇게 서버에 접속 시키고 전문을 전송하는 테스트를 하면

이쁘게 통신되는 모습입니다. ^ㅡ^
(테스트 영상입니다.)
다음편은 클라이언트로 찾아뵙겠습니다.
봐주셔서 감사합니다!
깔끔하게 만들어진 자료네요^^ 테스트에 사용된 클라이언트 프로그램도 작성하신거겠죠? 포스트 기다리겠습니당~
답글삭제좋은 글 너무 잘봤습니다!^^ 클라이언트는 언제쯤 포스트 해주시나요?ㅠㅠㅠㅠ
답글삭제113번째 라인 오타있습니다.
답글삭제buff.length 를 intLength로 바꿔야됩니다.
감사합니다.
답글삭제