채팅 프로그램 만들기
2) 채팅 프로그램 만들기 - 클라이언트 기능
잡동사니123
2023. 6. 16. 02:11
TCP 통신을 위한 구성
Form1 전체 코드
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace client
{
public partial class Form1 : Form
{
TcpClient client;
NetworkStream stream;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//소켓 만들기
client = new TcpClient();
//서버에 연결 시도
try
{
client.Connect("192.168.0.17", 8000);
//stream 얻기
stream = client.GetStream();
Thread handler = new Thread(message_Receive);
handler.IsBackground = true;
handler.Start();
}
catch (SocketException se)
{
receiveTextBox.Text = se.Message;
}
}
private void sendButton_Click(object sender, EventArgs e)
{
//stream에 메시지 보내기
byte[] buffer = Encoding.Unicode.GetBytes(sendTextBox.Text);
try
{
stream.Write(buffer, 0, buffer.Length);
}
catch (IOException ie)
{
receiveTextBox.Text = ie.Message;
}
}
private void message_Receive()
{
while(true)
{
//메시지 받기
byte[] recv = new byte[80];
try
{
int bytes = stream.Read(recv, 0, recv.Length);
string output = Encoding.Unicode.GetString(recv, 0, bytes);
if (receiveTextBox.InvokeRequired)
receiveTextBox.Invoke(new MethodInvoker(delegate { receiveTextBox.AppendText(output + Environment.NewLine); }));
else
receiveTextBox.AppendText(output + Environment.NewLine);
}
catch (IOException ie)
{
if (receiveTextBox.InvokeRequired)
receiveTextBox.Invoke(new MethodInvoker(delegate { receiveTextBox.AppendText(ie.Message + Environment.NewLine); }));
else
receiveTextBox.AppendText(ie.Message + Environment.NewLine);
return;
}
}
}
}
}
Form1_Load
private void Form1_Load(object sender, EventArgs e)
{
//소켓 만들기
client = new TcpClient();
//서버에 연결 시도
try
{
client.Connect("192.168.0.17", 8000);
//stream 얻기
stream = client.GetStream();
}
catch (SocketException se)
{
receiveTextBox.Text = se.Message;
}
Thread handler = new Thread(message_Receive);
handler.IsBackground= true;
handler.Start();
}
- Form1_Load : 폼이 생성될때 자동으로 실행되는 이벤트 함수
- client : TcpClient를 생성
- client.Connect : (ip,port번호) 에 해당하는 곳으로 연결을 시도함, ip와 port는 사용자 환경에 따라 수정 필자는 테스트 용이라 본인 컴퓨터 ip에 아무 포트번호 설정
- 스트림 얻기 : client의 스트림을 얻음
- 스레드 만들기 : 위 프로그램은 항상 메시지를 받도록 할 예정이므로 가만히 있든 메시지를 보내든 이상없이 메시지를 받을 수 있게 스레드를 만들어서 메시지르 받는 함수가 계속 돌아가게 함
sendButton_Click 이벤트
private void sendButton_Click(object sender, EventArgs e)
{
//stream에 메시지 보내기
byte[] buffer = Encoding.Unicode.GetBytes(sendTextBox.Text);
try
{
stream.Write(buffer, 0, buffer.Length);
}
catch (IOException ie)
{
receiveTextBox.Text = ie.Message;
}
}
- sendButton_Click : send 버튼 누를때마다 실행되는 이벤트 함수
- Encoding.Unicode.GetBytes : send박스에 입력했던 string을 byte로 변환해서 byte에 저장
- stream.Write : buffer의 내용을 서버로 전송함
message_Receive 함수
private void message_Receive()
{
while(true)
{
//메시지 받기
byte[] recv = new byte[80];
try
{
int bytes = stream.Read(recv, 0, recv.Length);
string output = Encoding.Unicode.GetString(recv, 0, bytes);
if (receiveTextBox.InvokeRequired)
receiveTextBox.Invoke(new MethodInvoker(delegate { receiveTextBox.AppendText(output + Environment.NewLine); }));
else
receiveTextBox.AppendText(output + Environment.NewLine);
}
catch (IOException ie)
{
if (receiveTextBox.InvokeRequired)
receiveTextBox.Invoke(new MethodInvoker(delegate { receiveTextBox.AppendText(ie.Message + Environment.NewLine); }));
else
receiveTextBox.AppendText(ie.Message + Environment.NewLine);
return;
}
}
}
- message_Receive : 쓰레드를 이용해 프로그램 종료까지 항상 실행되는 사용자가 만든 함수
- stream.Read : 서버에서 보낸 메시지를 읽어서 recv 배열에 저장
- Encoding.Uincode.GetString : 서버에서 받은 byte 메시지를 string으로 바꿔 output에 저장
- if문 : receive박스에 output을 출력하는 함수, 번거롭게 if문을 거치는 이유는 윈폼도 보이지 않는 스레드로 돌아가는데 그 스레드가 아닌 다른 스레드에서 값이 변경되면 오류가 나기 때문