UDP(User Datagram Protocol)
UDP(User Datagram Protocol)는 TCP와 같이 IP에 기반한 Transport Layer 프로토콜이다. UDP는 단 2가지 기능 만을 수행하는데, IP 위에 포트를 더하는 일과 데이타 Corruption을 감지해 불량 데이타를 폐기하는 일이다. TCP는 송수신 전에 반드시 연결(Connection)이 전제되어야 하는 반면, UDP는 별도의 연결이 필요없다.
비유하자면, TCP는 전화와 같이 통신 전에 미리 연결이 되어야 하고, UDP는 메일과 같이 주소만 알면 그냥 보낼 수 있다. UDP의 단점으로는 데이타가 중간에 유실될 수도 있고 데이타가 도달하는 순서도 뒤바뀔 수도 있다는 점이 있는데, UDP는 TCP와 달리 연결이 필요없고 통신 절차가 단순하기 때문에 더 효율적일 수 있으며, 데이타의 신뢰성이 그렇게 중요하지 않는 경우에는 유용하게 사용될 수도 있다.
예를 들어, 비디오 스트리밍이나 Skype, 연속적인 날씨 데이타, 주식 시세 등과 같이 뒤에 계속 데이타가 들어 오기 때문에 중간에 데이타 하나가 유실되더라도 크게 문제가 없는 경우 UDP가 많이 사용된다. UDP는 또한 Broadcast와 Multicast에 유용하게 사용된다.
UDP 클라이언트 - C# 프로그래밍 배우기 (Learn C# Programming)

어떤 통신 관련 하드웨어 기술이든 IP만 구현하면 되고, 어떤 응용 프로그램이든 IP위에서만 동작하면 된다는 의미를 내포하는 그림
유선 랜(Ethernet)과 Wifi 모두 IP 주소를 쓰고, Bluetooth, LTE, 3G 도 통신 할 때는 IP 주소를 부여 받아 통신한다.
소켓 통신
포트 : 통신을 하기 위한 출입구, IP로 해당 PC에 접근은 했지만 PC 내부에서 어느 프로그램과 통신을 해야하는지 구분함
소켓 : 각 포트를 사용하여 통신을 수행하는 도구라고 생각하면 된다. 각각 프로그램에 포트를 세팅해 놓기만 하면 알아서 통신이 되는 것이 아니고, 이 소켓으로 데이터를 주고 받는 것이다. 즉 포트는 출입구 역할, 소켓은 출입구를 통하여 데이터를 직접 송수신하는 매체 인 것이다.

- 서버 소켓과 클라이언트 소켓으로 나뉜다.
- 서버 소켓의 역할은 클라이언트 소켓의 연결 요청을 대기하고, 연결 요청이 오면 클라이언트 소켓을 생성하여 통신을 가능하게 한다.
- 클라이언트 소켓은 대기하는 것 없이 바로 사용가능하며, 실제로 데이터 송수신이 일어나는 것은 클라이언트 소켓이다.
UDP와 TCP의 차이를 알기 위한 비유
UDP - 편지 : 편지지에 데이터를 기록 후 편지봉투에 상대방의 주소와 자신의 주소를 표시한 후 그냥 보냄. 편지가 도착했는 지 알 수 없음
TCP - 통화 : 상대방의 전화번호(IP 주소와 Port)를 알고 있어야 연결 요청 가능, 받지않으면 계속 대기해야함. 어느 순간에 전화 거는 것을 포기하는 것도 마찬가지로 서버 연결 포기 가능

1. 특징
- 전송하는 데이터 양에 제한을 받지않는다
- 신뢰성을 보장하지 않는다
- 전용회선을 형성하지 않아 보낸 데이터가 순서대로 도착한다는 보장이 없다.
2. 장점
- 흐름제어가 없고 신뢰성을 보장하지않아 프로토콜이 단순, 가볍다.
— > TCP보다 더 빠른 속도로 데이터 처리
- 비연결 지향형 —> 소스를 적게 사용
: 데이터 전송 회선을 형성X, 전송이 필요한 시점에만 리소스를 사용(효율성good)
- 단점: 데이터가 순서대로 도착하지 않을 수 있음
3. UDP 네트워크 프로그램의 특징
UDP의 데이터 송 수신을 위해 SendTo , ReceiveFrom 메소드를 제공
UdpClient 사용법(예제)
UDP를 사용하기 위해서는 System.Net.Sockets 네임스페이스 안의 UdpClient 클래스나 Socket 클래스를 사용한다. TCP와 달리 UDP는 별도의 UDP 서버 클래스가 없으며, 서버도 UdpClient 클래스를 사용한다.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using static System.Console;
namespace UdpCli
{
class Program
{
static void Main(string[] args)
{
// (1) UdpClient 객체 성성
UdpClient cli = new UdpClient();
string msg = "안녕하세요";
byte[] datagram = Encoding.UTF8.GetBytes(msg);
// (2) 데이타 송신
cli.Send(datagram, datagram.Length, "127.0.0.1", 7777);
WriteLine("[Send] 127.0.0.1:7777 로 {0} 바이트 전송", datagram.Length);
// (3) 데이타 수신
IPEndPoint epRemote = new IPEndPoint(IPAddress.Any, 0);
byte[] bytes = cli.Receive(ref epRemote);
WriteLine("[Receive] {0} 로부터 {1} 바이트 수신", epRemote.ToString(), bytes.Length);
// (4) UdpClient 객체 닫기
cli.Close();
}
}
}- UDP 통신을 위해 System.Net.Sockets 네임스페이스의 UdpClient 객체를 생성한다. UdpClient 생성자에서 서버와 포트를 줄 수도 있지만, 만약 하나의 UdpClient 객체로 여러 서버에 데이타를 보낼 경우는 Send() 메서드에서 서버와 포트를 지정한다.
- UdpClient 객체의 Send() 메서드를 사용하여 데이티(UDP에서 datagram 이라 함)를 서버로 보낸다. 네트워크 데이타 송수신은 기본적으로 바이트 데이타를 사용하는데, 따라서 문자열을 보낼 경우 먼저 바이트로 인코딩한 후 보내게 된다. 보통 일반 영문은 ASCII로 인코딩하고, 한글 등 비영문 문자열은 UTF 인코딩을 사용한다.UDP 데이타그램은 최대 65,507 바이트까지 전송할 수 있다.
- UDP에서 데이타를 수신할 경우는 UdpClient 객체의 Receive() 메서드를 사용한다. Receive() 메서드는 특히 수신 데이타와 함께 상대 컴퓨터의 종단점(IP주소와 포트) 정보도 같이 전달받는데, 이를 위해 IPEndPoint 객체를 ref 파라미터로 전달한다. 이를 통해 데이타가 수신되면 누가 그 데이타를 전송했는지 알 수 있다. TCP와 달리 UDP는 Connectionless 프로토콜이기 때문에 이렇게 누가 보낸 데이타인지를 알 필요가 있다.
- 마지막으로 UdpClient 객체를 닫는다.
TCPChatClient 예제(feat. 김기용 교수님)
https://nshj.tistory.com/entry/C-기초문법-11-쓰레드Thread와-테스크Task
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;
namespace TCPChatClient
{
public partial class TCPChatClient : Form
{
private TCPClient m_clientSocket;
private string m_strServerIpAddr;
private int m_iServerPort;
public TCPChatClient()
{
InitializeComponent();
}
public void outputMessage(string msg)
{
try
{
this.Invoke(new MethodInvoker(
delegate()
{
richTextBox_Output.AppendText(msg);
richTextBox_Output.AppendText(Environment.NewLine);
richTextBox_Output.ScrollToCaret();
}
));
}
catch (InvalidOperationException)
{
//throw new Exception(ex.Message);
}
}
public void connectToServer()
{
outputMessage("Connected to Server");
}
public void recvFromServer(byte[] buffer)
{
outputMessage(Encoding.Default.GetString(buffer));
}
public void disconnectToServer()
{
outputMessage("Disconnected to Server");
}
private void TCPChatClient_Load(object sender, EventArgs e)
{
}
private void textBox_Message_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
// TextBox에서 Enter키를 눌렀을 때
button_Send.PerformClick();
}
}
private void button_Send_Click(object sender, EventArgs e)
{
if (textBox_Message.Text.Length > 0)
{
// Message 전송
// TextBox 초기화
m_clientSocket.sendPacket(Encoding.UTF8.GetBytes(textBox_Name.Text + " : " + textBox_Message.Text));
textBox_Message.Text = "";
}
}
private void button_Disconnect_Click(object sender, EventArgs e)
{
m_clientSocket.disconnect();
}
private void button_Connect_Click(object sender, EventArgs e)
{
ConnectDlg dlg = new ConnectDlg();
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
m_strServerIpAddr = dlg.m_strIPAddr;
m_iServerPort = dlg.m_iPort;
m_clientSocket = new TCPClient(this);
m_clientSocket.connect(m_strServerIpAddr, m_iServerPort);
}
}
private void TCPChatClient_FormClosing(object sender, FormClosingEventArgs e)
{
if (m_clientSocket != null)
{
m_clientSocket.disconnect();
}
}
}
}출처 :
'Programming > C#' 카테고리의 다른 글
| IP 주소와 호스트(C#을 통한 통신 프로그램) (0) | 2020.03.05 |
|---|
