[TCP/IP 소켓 프로그래밍] Winform 을 이용한 채팅 프로그램 - 3
각 클라이언트에서 작성한 메시지를 서버로 보내보는 작업까지 완료해보았다. 이제 조금 더 채팅 프로그램 스럽게 만들 수 있도록 각 클라이언트에서 보낸 메시지를 채팅 창에 띄워주는 작업을 해보자.
서버에서 클라이언트로 메시지 보내기
클라이언트에서 TcpClient 와 NetworkStream 을 이용해서 서버로 메시지를 전송했듯, 서버에서도 마찬가지로 메시지를 클라이언트 단으로 넘겨줄 수 있다. 그러면 일단 서버에서 클라이언트로 메시지를 넘기는 작업을 해보자.
public static void RecvMsgFromClient(CLIENT_TYPE ClientType)
{
while (true)
{
byte[] Buff = new byte[1024];
int Nbytes;
string ReceiveData = "";
if(ClientType == CLIENT_TYPE.FIRST)
{
while ((Nbytes = FirstClientStream.Read(Buff, 0, Buff.Length)) > 0)
{
ReceiveData = Encoding.Unicode.GetString(Buff, 0, Nbytes);
Console.WriteLine("1번 클라이언트 : " + ReceiveData);
SendMsgToClient(SecondClientStream, Buff);
}
}
if(ClientType == CLIENT_TYPE.SECOND)
{
while ((Nbytes = SecondClientStream.Read(Buff, 0, Buff.Length)) > 0)
{
ReceiveData = Encoding.Unicode.GetString(Buff, 0, Nbytes);
Console.WriteLine("2번 클라이언트 : " + ReceiveData);
SendMsgToClient(FirstClientStream, Buff);
}
}
}
}
public static void SendMsgToClient(NetworkStream Stream, byte[] Msg)
{
Stream.Write(Msg);
Stream.Flush();
}
기존에 서버로 메시지를 보내는 테스트에서 작성했던 코드에서 약간 수정이 필요하다. 기존에는 메시지를 서버로 보내기만 하면 됐기 때문에 단순하게 Client 의 Type 만 체크한 뒤, 서버 콘솔 쪽에 메시지를 띄워주었다.
다만, 이제는 1번 클라이언트에서 받아온 메시지를 2번 클라이언트로 넘겨주어야 한다. 이 과정에서 1번 클라이언트의 Stream 과 2번 클라이언트의 Stream 을 구분해주어야 할 필요성이 생겼다. 그래서 각 Stream 을 전역변수로 설정해주고, 1번 클라이언트에서 메시지를 받을 때는 1번 클라이언트에 연결된 Stream 을, 받아온 메시지를 2번 클라이언트에 넘겨줄때는 2번 클라이언트에 연결된 Stream 을 사용했다.
Stream 을 잘 구분해 준 뒤, 이 Stream 을 이용해서 Write() 함수를 호출하면 서버에서 클라이언트로 메시지를 보내줄 수 있다.
클라이언트에서 메시지 받기
서버에서 보내준 메시지를 이제 클라이언트 단에서 받아보자. 이 과정에서는 각 클라이언트에 하나의 Thread 를 추가한 뒤, Thread 가 하는 작업으로는 메시지를 받는 작업을 추가해주면 될것같다. 이 부분은 사실 서버에서 메시지를 받는 로직을 참고하면 좋다. 받아온 메시지는 일단 테스트용으로 바로 TextBox 에 추가해서 메시지가 잘 도착했는지 확인만 해보자.
private void RecvMsg()
{
while (true)
{
if (Stream == null)
{
continue;
}
byte[] Buff = new byte[1024];
int Nbytes;
string ReceiveData = "";
while ((Nbytes = Stream.Read(Buff, 0, Buff.Length)) > 0)
{
ReceiveData = Encoding.Unicode.GetString(Buff, 0, Nbytes);
BeginInvoke(new Action(() =>
{
// UI 작업은 여기에서 수행됩니다.
textBox_RecvMsg.Text = ReceiveData;
}));
}
}
}
RecvMsg() 함수는 별도의 Thread 를 하나 생성해주고, 클라이언트쪽 Form 이 생성될 때 실행되는 함수다. 이를 이용해서 서버에서 보내지는 메시지를 가져올 수 있으며, 가져온 메시지를 이용해서 UI 에 뿌려줄 수 있다. 단, Thread 내에서 UI 를 변경하는것은 허용되지 않기 때문에 BeginInvoke 함수를 이용해서 UI 변경을 처리해주면 완료. 아래와 같은 결과가 나오게 된다.

메시지를 잘 받아봤으니, 이제 받아온 메시지를 UI 상에 이쁘게 꾸며주기만 하면 좋을것같다. 다음번에는 채팅 UI 를 추가해서 진짜 채팅처럼 만들어보자.