핵심 원리
TCP 연결이 수립된 뒤 NetworkStream(네트워크 스트림)을 통해 데이터를 전송합니다.
네트워크는 바이트 배열 byte[]만 전송할 수 있으므로 텍스트를 먼저 바이트로 인코딩하고, 수신 후 디코딩해 문자열로 복원해야 합니다.
텍스트 외에도 파일, 이미지를 바이트 배열로 변환해 전송할 수 있습니다. 이 절에서는 먼저 텍스트 채팅을 구현합니다.
주요 API 설명
- 서버 측
listener.AcceptTcpClient()
- 블로킹 메서드(대기 상태):클라이언트 연결 요청이 들어올 때까지 스레드가 일시 정지합니다;
- 해당 클라이언트 연결을 나타내는
TcpClient객체를 반환합니다; tcpClient.GetStream()로 네트워크 스트림을 가져옵니다.
- 네트워크 스트림 읽기·쓰기
stream.Write(바이트배열,시작위치,길이):데이터 전송stream.Read(버퍼배열,시작위치,최대읽기길이):데이터 수신,실제 읽은 바이트 길이를 반환
- 인코딩 주의사항
예제 코드는Encoding.Unicode(UTF‑16)를 사용합니다. 송수신 양쪽의 인코딩은 반드시 동일해야 하며, 그렇지 않으면 깨진 문자가 발생합니다.
서버 WinForms
컨트롤:textBoxIP、textBoxPort、textBoxInfo(메시지 표시 상자)
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace TcpServer
{
public partial class Form1 : Form
{
IPAddress ip;
TcpListener listener;
TcpClient tcpClient;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
ip = IPAddress.Parse(textBoxIP.Text);
listener = new TcpListener(ip, Convert.ToInt32(textBoxPort.Text));
listener.Start();
textBoxInfo.Text = $"服务器启动-{DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
// 阻塞!主线程卡住
tcpClient = listener.AcceptTcpClient();
textBoxInfo.Text = $"连接成功-{DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
NetworkStream stream = tcpClient.GetStream();
byte[] byteArray = new byte[1024];
// 阻塞等待客户端发送消息
int length = stream.Read(byteArray, 0, 1024);
string receiveMessage = Encoding.Unicode.GetString(byteArray, 0, length);
textBoxInfo.Text = $"接收到:{receiveMessage}-{DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
}
}
}Code language: PHP (php)
클라이언트 WinForms
컨트롤:textBoxIP、textBoxPort、textBoxInfo、textBoxInput(입력 상자)buttonStart【연결】、buttonSend【전송】
using System;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace TcpClientChat
{
public partial class Form1 : Form
{
TcpClient tcpClient;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
tcpClient = new TcpClient();
try
{
tcpClient.Connect(textBoxIP.Text, Convert.ToInt32(textBoxPort.Text));
textBoxInfo.AppendText("连接成功!\r\n");
}
catch (Exception ex)
{
MessageBox.Show("连接失败-" + ex.Message);
}
}
private void buttonSend_Click(object sender, EventArgs e)
{
string message = textBoxInput.Text;
textBoxInfo.Text = $"发送“{message}”-{DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
NetworkStream stream = tcpClient.GetStream();
byte[] byteArray = Encoding.Unicode.GetBytes(message);
stream.Write(byteArray, 0, byteArray.Length);
}
}
}Code language: PHP (php)
위 코드는 클라이언트와 서버 간 메시지 전송 기능을 구현합니다.
클라이언트‑서버 통신
Previous: TcpClient 클라이언트