이번 수업에서는 클라이언트를 생성한 뒤 클라이언트에서 서버에 연결하는 과정을 다룹니다.
이전 단원의 서버 코드(TcpListener)와 이번 절의 클라이언트(TcpClient)를 결합하여 단계별로 TCP 채팅 도구를 구현해 보겠습니다.
개념 구분
- 서버: TcpListener
고정 IP + 고정 포트(9500)에 바인딩합니다. 지속적으로 수동 대기하며 여러 클라이언트 접속을 동시에 받아들일 수 있습니다. 물건을 파는 상점이 손님을 기다리는 모습과 같습니다. - 클라이언트: TcpClient
포트를 수동으로 바인딩할 필요가 없습니다. 운영체제가 무작위 임시 포트를 자동 할당하고 서버의 고정 9500 포트로 능동 접속을 시도합니다.
통신 양쪽의 포트는 일치하지 않습니다
클라이언트 무작위 포트 — 서버 고정 9500
콘솔 클라이언트
using System;
using System.Net.Sockets;
namespace TalkClient
{
class Program
{
static void Main(string[] args)
{
// TCP 클라이언트 객체 생성
TcpClient tcpClient = new TcpClient();
// 로컬 127.0.0.1:9500 서버에 접속합니다. 다른 컴퓨터일 경우 해당 컴퓨터 IP를 입력하세요. 서버와 클라이언트가 같은 PC에 있을 필요는 없습니다.
tcpClient.Connect("127.0.0.1", 9500);
// LocalEndPoint: 로컬 클라이언트 주소·포트
// RemoteEndPoint: 원격 서버 주소·포트
Console.WriteLine("접속 성공, 로컬 포트 {0}, 서버 포트{1}",
tcpClient.Client.LocalEndPoint,
tcpClient.Client.RemoteEndPoint);
Console.ReadLine();
tcpClient.Close();
}
}
}Code language: JavaScript (javascript)
WinForms 클라이언트 코드
UI 컨트롤 목록:
textBoxIP:서버 IP 주소textBoxPort:서버 포트 번호buttonStart:【접속】버튼textBoxInfo:메시지 표시 상자textBoxMsg:전송할 메시지 입력 상자buttonSend:전송 버튼
using System;
using System.Net.Sockets;
using System.Windows.Forms;
namespace SocketChatClient
{
public partial class Form1 : Form
{
TcpClient tcpClient;
public Form1()
{
InitializeComponent();
}
// 접속 버튼 클릭 이벤트
private void buttonStart_Click(object sender, EventArgs e)
{
tcpClient = new TcpClient();
try
{
string ip = textBoxIP.Text;
int port = Convert.ToInt32(textBoxPort.Text);
tcpClient.Connect(ip, port);
textBoxInfo.AppendText($"접속 성공! 로컬 엔드포인트:{tcpClient.Client.LocalEndPoint}\r\n");
}
catch (Exception ex)
{
MessageBox.Show("접속 실패‑" + ex.Message);
}
}
}
}Code language: PHP (php)
서버 + 클라이언트 연동 절차
- 먼저서버 프로그램을 실행하고 시작 버튼을 눌러
TcpListener.Start()로 9500 포트 수신 대기를 시작합니다 - 그 뒤클라이언트 프로그램을 실행하고 접속 버튼을 누르면
TcpClient.Connect()가 TCP 3‑way 핸드셰이크를 수행합니다 - 접속 완료 후
NetworkStream을 통해 양방향 메시지를 주고받습니다(다음 장 내용)
유의사항
- 접속 실패의 흔한 원인
- 실행 순서 오류: 서버를 먼저 실행하지 않음
- IP/포트 번호가 일치하지 않음
- 방화벽 차단. 여러 대 컴퓨터에서 디버깅할 때는
127.0.0.1대신 LAN IP를 사용하세요
- 포트 관련 지식
- 서버는 9500 포트를 고정으로 사용하며 여러 클라이언트 접속을 동시에 수용 가능
- 클라이언트 포트는 운영체제가 무작위로 할당하며 실행할 때마다 달라지므로 직접 지정할 필요가 없습니다
- 블로킹 경고
폼 프로그램에서.Connect()를 직접 호출하면 UI 스레드가 블로킹됩니다. 실제 프로젝트에서는 비동기ConnectAsync를 사용해 창이 멈추는 현상을 막으세요.
복습: 서버 WinForms(이전 단원)
using System;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;
namespace SocketChatServer
{
public partial class Form1 : Form
{
IPAddress ip;
TcpListener listener;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
ip = IPAddress.Parse(textBoxIP.Text);
int port = Convert.ToInt32(textBoxPort.Text);
listener = new TcpListener(ip, port);
listener.Start();
textBoxInfo.Text = $"서버 시작 {DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
}
}
}Code language: C# (cs)
클라이언트
Previous: 서버 측 포트 수신 대기
Next: 클라이언트‑서버 통신