Project History/다중 기능을 포함한 채팅 프로그램

[C# 채팅 프로그램 #03] TCP/IP통신에서 특정 클라이언트에게만 메세지 보내기

JeongKyun 2022. 2. 10.
반응형

보통 패킷을 주고받는 tcp/ip 통신서버에서 현재 연결되어있는 여러 소켓중 특정 클라이언트 소켓에만 보내는 방법에 대해 여러 가지 고민을 해봤다. 

 

해당 기능을 구현할 때 까지의 흐름은 이랬다 연결하는 소켓의 핸들러id를 배열에 담아두었다가 사용하면 되지않을까? 

근데 그럴려면 다중 소켓이 순서 상관없이 마구 접속해있다는 가정하에 원하는 클라이언트를 어떻게 찾을 수 있을까?? 이러한 문제에 또 봉착했다.

 

근데 생각해보니 그냥 처음 클라이언트가 접속할때 고유ID를 받아놓고 컬렉션에 고유ID와 해당 소켓을 담아두고 특정 장비에게 보낼 때 컬렉션에서 선택한 아이디를 찾아 해당 소켓을 Send하면 되지 않을까?라는 생각에 아 이거다 하고 바로 진행하였다.

 

진행 후에 다른 사람들은 어떻게 할지 찾아본 결과 비슷하게 진행됐다. 예로 키오스크 개발을 한다하면 키오스크 서버에게 장비 코드들을 처음에 보내고 서버에서 관리하는 형식으로 하는 것으로 어떻게 보면 똑같았다. 무튼 이제 나의 이 방식으로 개발한 방식을 공유해보려한다.

 

이미 이전글을 다 본 사람이라면 어떻게 한지 대충 느낌이 온 사람도 있겠지만 해당 부분은 공을 많이 들인것도 있기에 따로 글로 다시 정리하는 이유도 있다.

 

클라이언트

이런식으로 서버에게 보낼 때 어떤 장비는 연결이 끝나고 오분뒤에 새로 연결하는 장비가 있을 수 있으니 메세지가 올 때 처음 연결한건지 아님 이미 연결하고 그냥 기본 메세지인지 구분을 지기위해 type이라는 키를 만들어 주었고 서버에서는 이제 type이 init이면 해당 text를 사용자ID로 넣고 그때 접속한 소켓을 한 세트로 컬렉션에 넣는 작업을 한다.

 

서버

클라이언트에서 저렇게 Send할 경우 서버에서는 위와 같이 json 형식으로 받게된다. 이제 string으로 "text"의 value값을 뽑아와 user객체에 사용자 이름을 넣어두고 Dictionary<String, socket> dic_client의 컬렉션에 해당 이름과 소켓을 넣어둔다.

 

그리고 서버에서 이제 특정 클라이언트에게 보내는 방법의 로직은 이렇다.

위와 같이 Dictionary.ContainsKey를 활용하여 사용자의 이름을 찾고 해당 소켓으로 Send하는 형식으로 해주었다. 이렇게 구현하니 원하는 방식대로 문제없이 진행되었다.

 

이제 남은것이 해당 메세지들을 암호화, 복호화 하는 작업이 남아있으며 해당 작업까지 끝나면 마지막 동작하는 영상까지 해서 마무리할려한다.

 

혹시 이 글을 읽은 분들중에 특정 클라이언트에게 보내는 다른 방법이 있는 것을 아는 분이 있다면 댓글로 공유해주면 감사하겠다. 또 그러한 댓글들이 다른 의문을 가진 사람들에게 많은 도움이 될 것 같다. 나도 아직 해당 부분은 미숙한 부분이기에 분명 다른 방법도 있을거라 생각하고 이후에 또 다른 방법이 있다면 이 글에 추가로 달아보겠다.

 

이후 패킷 암복호화까지 마무리하고 최종 완성 영상에서 봅시다!

댓글

💲 많이 본 글