클라이언트‑서버 통신

핵심 원리

TCP 연결이 수립된 뒤 NetworkStream(네트워크 스트림)을 통해 데이터를 전송합니다.
네트워크는 바이트 배열 byte[]만 전송할 수 있으므로 텍스트를 먼저 바이트로 인코딩하고, 수신 후 디코딩해 문자열로 복원해야 합니다.

텍스트 외에도 파일, 이미지를 바이트 배열로 변환해 전송할 수 있습니다. 이 절에서는 먼저 텍스트 채팅을 구현합니다.

주요 API 설명

  1. 서버 측
    listener.AcceptTcpClient()
  • 블로킹 메서드(대기 상태):클라이언트 연결 요청이 들어올 때까지 스레드가 일시 정지합니다;
  • 해당 클라이언트 연결을 나타내는 TcpClient 객체를 반환합니다;
  • tcpClient.GetStream()로 네트워크 스트림을 가져옵니다.
  1. 네트워크 스트림 읽기·쓰기
  • stream.Write(바이트배열,시작위치,길이)데이터 전송
  • stream.Read(버퍼배열,시작위치,최대읽기길이)데이터 수신,실제 읽은 바이트 길이를 반환
  1. 인코딩 주의사항
    예제 코드는 Encoding.Unicode(UTF‑16)를 사용합니다. 송수신 양쪽의 인코딩은 반드시 동일해야 하며, 그렇지 않으면 깨진 문자가 발생합니다.

서버 WinForms

컨트롤:
textBoxIPtextBoxPorttextBoxInfo(메시지 표시 상자)

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

컨트롤:
textBoxIPtextBoxPorttextBoxInfotextBoxInput(입력 상자)
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)

위 코드는 클라이언트와 서버 간 메시지 전송 기능을 구현합니다.

클라이언트‑서버 통신

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다