π 곡λΆνλ μ§μ§μνμΉ΄λ μ²μμ΄μ§?
[리λ μ€ λ€νΈμνΉ νλ‘κ·Έλλ°] UDP λ€νΈμν¬ νλ‘κ·Έλλ° λ³Έλ¬Έ
[리λ μ€ λ€νΈμνΉ νλ‘κ·Έλλ°] UDP λ€νΈμν¬ νλ‘κ·Έλλ°
μ§μ§μνμΉ΄ 2024. 1. 30. 20:02<μμμ§ λμ μ¬λ¬ΌμΈν°λ·μ μν 리λ μ€ νλ‘κ·Έλλ° with λΌμ¦λ² 리νμ΄ μμ μ μ°Έκ³ ν΄μ μμ±νμμ΅λλ€ :-)>
β μμΌμ μ΄μ©
UDP νλ‘ν μ½μ λ°μ΄ν°μ μ μ‘ μ μ λ’°μ±μ μμ§λ§ μλκ° λΉ λ₯΄κΈ° λλ¬Έμ μΌλ°μ μΈ LAN νκ²½μμ λ§μ΄ μ¬μ©
LAN μμμλ ν¨ν·μ λΆμ€μ΄ κ±°μ μλ€κ³ ν¨
μλ²μ κ²½μ° bind() ν¨μλ₯Ό μ¬μ©νμ¬ μ΄μ체μ μ ν΄λΉ ν¬νΈλ‘ λ€μ΄μ€λ μλΉμ€λ₯Ό UDP μλ²μμ μ¬μ©ν μ μλλ‘ μ°κ²°ν΄μ€μΌ νλ€
UDPμλ²μ ν΄λΌμ΄μΈνΈ λͺ¨λ sendto() ν¨μλ₯Ό ν΅ν΄μ λ°μ΄ν°κ·Έλ¨μ 보λ΄κ³ , recvfrom) ν¨μλ₯Ό ν΅ν΄ λ°μ΄ν°κ·Έλ¨μ μμ νλ€
μμΌ μ¬μ©μ΄ λλλ©΄ close() ν¨μλ₯Ό μ¬μ©νμ¬ μμΌμ λ«λλ€
μ λμ€μμ μΈν°λ· ν΅μ μ νκΈ° μν΄μλ λ¨Όμ μμΌμ μμ±ν΄μΌ νλλ°, socket() ν¨μλ₯Ό μ¬μ©νλ€
νΈμΆμ μ±κ³΅νλ©΄ μμΌμ λν νμΌ λμ€ν¬λ¦½ν°λ₯Ό λ°ννκ³ , μ€ν¨νλ©΄ -1μ λ°ννλ€
int socket(int domain, int type, int protocol);
domain : μμΌμ ν΅μ λ°©μ
μΈν°λ·μΌλ‘ ν΅μ ν κ²μΈμ§, λ΄λΆμ μΈ νμΌ μμ€ν μ μ΄μ©ν΄ ν΅μ ν κ²μΈμ§
λλ©μΈ | λ΄μ© | λΉκ³ |
PF_INET, AF_INET | IPv4 μΈν°λ· νλ‘ν μ½ μ¬μ© | |
PF_INET6, AF_INET6 | IPv6 μΈν°λ· νλ‘ν μ½ μ¬μ© | |
PF_LOCAL, AF_LOCAL | κ°μ μ λμ€ μμ€ν λ΄μμ νλ‘μΈμ€λΌλ¦¬ ν΅μ νλ€ | PF_UNIX, AF_UNIX |
PF_PACKET, AF_PACKET | μ μμ€ μμΌ μΈν°νμ΄μ€ μ¬μ© | SOCKET_PACKET |
PF : Protocol Family
AF : Address Family
type : μμΌμ μ μ‘ λ°©μ
μμΌμ TCP, UDP λ₯Ό μ§μνλ©°, IPλ₯Ό μ§μ μ΄μ©νκ±°λ μ§μ νλ‘ν μ½μ λ§λ€ λ μ¬μ©ν μ μλ Raw μμΌλ μ§μ
μ€νΈλ¦Ό μμΌμ TCP κΈ°λ° μ λ’°μ± νμν ν΅μ μ μ΄μ©
λ°μ΄ν°κ·Έλ¨ μμΌμ UPD κΈ°λ° μ λ’°μ± μλ λΉ λ₯Έ ν΅μ μ μ΄μ©
νμ | μμ | λ΄μ© |
μ€νΈλ¦Ό μμΌ | SOCKET_STREAM | μ°κ²° μ§ν₯ν TCP κΈ°λ° μμΌ κ°μ μ°κ²° ν λ°μ΄ν° μ μ‘ |
λ°μ΄ν°κ·Έλ¨ μμΌ | SOCKET_DGRAM | λΉμ°κ²°νμ UDP κΈ°λ° μ‘μμ μ λμ°©μ§ μ£Όμ νμ |
Raw μμΌ | SOCKET_RAW | μ μμ€ νλ‘ν μ½ μ κ·Ό IP κ³μΈ΅μ μ΄μ©νλ©° ICMP, OSPF λ±μ΄ μ¬μ©λ¨ |
protocol : λ€νΈμν¬ νλ‘ν μ½
보ν΅μ 0μ κ°μ λ§μ΄ μ¬μ©ν¨ (κ°κ°μ νμ¬λ³λ‘ λ€μν νλ‘ν μ½ μ¬μ©νμ§λ§, μ£Όλ‘ TCP/IPκ° μ¬μ©λλ μ€)
β μλ²λ₯Ό μν bind() ν¨μ
UDP μλ²λ₯Ό μμ±νκΈ° μν΄μλ bind() ν¨μλ₯Ό μ¬μ©ν΄μ ν΄λΌμ΄μΈνΈλ‘λΆν° λ€μ΄μ€λ μλΉμ€λ₯Ό νμ¬μ μ ν리μΌμ΄μ μ΄ μ¬μ©ν μ μλλ‘ ν΄λΉ ν¬νΈλ₯Ό μ΄μ체μ μ λ±λ‘νλ μμ μ μνν΄μΌ νλ€
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd : socket() ν¨μλ₯Ό ν΅ν΄ λ°νλ°μ μμΌμ νμΌ λμ€ν¬λ¦½ν°
*addr : UDP μλ²μ μ£Όμ μ 보
addrlen : μ£Όμ ν¬κΈ°
μ λμ€ λ΄λΆμμ ν΅μ μ μ¬μ©νλ κ²½μ° socketaddr_un ꡬ쑰체λ₯Ό μ¬μ©νλ©° μ£Όμλ‘ νμΌ μμΉλ₯Ό μ¬μ©
λ€νΈμν¬ ν΅μ μ μ¬μ©νλ κ²½μ° sockaddr_in ꡬ쑰체λ₯Ό μ¬μ©νλ©° μλ²μ IP μ£Όμμ ν¬νΈ λ²νΈλ₯Ό μ¬μ©
μ΄ λ ꡬ쑰체λ₯Ό νλλ‘ ν΅ν©νλ κ΅¬μ‘°μ²΄κ° sockaddr ꡬ쑰체
β λ°μ΄νΈ μμ λ³ν
λ€νΈμν¬ μλ²λ‘ λ§μ΄ μ¬μ©λμλ SUN μμ μ¬μ©νλ RISC CPU μ IBM PC μμ μ¬μ©νλ μΈν μ x86 CPUλ λ©λͺ¨λ¦¬μ λ°μ΄ν°λ₯Ό μ μ₯νλ λ°©μμ΄ λ€λ₯΄λ€
μΈν μ x86μ΄λ DECμ νλ‘μΈμ€μμ μ¬μ©νλ 리ν μλμ λ°©μμ΄ κ°μ₯ μμ κ°μ λ°μ΄νΈλΆν° λ¨Όμ νμ λ¨
16μ§μ 1A2B3C4D -> 4D3C2B1A
IBM 370 μ»΄ν¨ν°μ μ¬ λ§μ΄ν¬λ‘μμ€ν μ¦μ SPARC λ± RISC λ°©μμ μν¬μ€ν μ΄μ μ© CPUλ€μ λΉ μλμ μ¬μ©
λ€νΈμν¬μμμλ μμ°¨μ μΌλ‘ λ°μ΄ν°κ° μ μ‘λλλ° λΉ μλμμ΄ λ μ ν©νλ€
λ€νΈμν¬ λ°μ΄νΈ μμ (Network Byte Order) μ μ‘/μμ λ°μ΄ν° λͺ¨λ λΉ μλμμΌλ‘ κ°μ£Όν΄μ μ²λ¦¬ν΄μΌ ν¨
PCμμ μ¬μ©λκ³ μλ CPUλ μΈν κ³μ΄μ CPU μ΄κΈ° λλ¬Έμ μλμ λ³νμ΄ νμν μ μλλ°, μ λμ€λ νΈμ€νΈ λ°μ΄νΈ μμμμ λ³νμ μν λ€μν ν¨μλ€μ μ 곡νκ³ μλ€
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
μλμ λ³ν λ°©ν₯μλ hton λ°©ν₯κ³Ό ntoh λ°©ν₯μ΄ μλ€
hton μ νΈμ€νΈμμ λ€νΈμν¬ λ°μ΄νΈ μμ (host to network)
ntoh μ λ€νΈμν¬μμ νΈμ€νΈ λ°μ΄νΈ μμ (network to host)
μ λ―Έμ΄λ λ³ν ν¬κΈ°λ₯Ό λνλλ©°, s λ short(16λΉνΈ), l μ long(32λΉνΈ)
IPv4μ IP μ£Όμλ 32λΉνΈμ΄λ―λ‘ htonl() ν¨μ, ν¬νΈ λ²νΈλ 16μ§μμ΄λ―λ‘ htons()
hλ νΈμ€νΈ, beλ λΉ μλμ, leλ 리ν μλμ
μ«μλ λΉνΈ μ
β λ€νΈμν¬ μ£Όμ λ³ν
λ€νΈμν¬μ μ£Όμλ IP μ£Όμ μ΄κ±°λ λλ©μΈ λ€μ
IP μ£Όμλ soctaddr_in ꡬ쑰체μ sin_addr νλͺ©μμ μ¬μ©νλ κ°μ 16μ§μμ μ μκ° μ΄λ―λ‘ μ΄ λ¬Έμμ΄μ 16μ§μλ‘ λ³ννλ€
ν¨μ | λ΄μ© | λΉκ³ |
inet_pton() | λ¬Έμμ΄ ννμ IPμ£Όμλ₯Ό μ«μ ννμ IP μ£Όμλ‘ λ³ν | inet_aton() λλ inet_addr() |
inet_ntop() | μ«μ ννμ IPμ£Όμλ₯Ό λ¬Έμμ΄ ννμ IP μ£Όμλ‘ λ³ν | inet_ntoa() |
inet_network() | IPμ£Όμλ₯Ό νΈμ€νΈ μμμμ λ€νΈμν¬ μμλ‘ λ³ννλ€ |
β UDP λ°μ΄ν°μ μ‘μμ
TCP λ μλ²κ° μ°κ²°λμ΄ μμΌλ―λ‘ read() λ write() κ°μ νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ‘°μνλ ν¨μλ₯Ό μ΄μ©ν΄μ λ°μ΄ν° μ‘μμ
UDP λ μλ²κ° μ°κ²°λμ΄ μμ§ μμΌλ―λ‘ λ€λ₯Έ ν¨μλ₯Ό μ¬μ©ν¨, sendto() ν¨μμ recvfrom()
UDP λ sendto() ν¨μμ λ°μ΄ν°λ₯Ό λ°μ μλλ°©μ μ 보 (μ£Όμμ ν¬νΈλ²νΈ)λ₯Ό μ λ ₯νκ³ recvfrom() ν¨μλ₯Ό μ΄μ©ν΄μ λ°μ΄ν°λ₯Ό λ³΄λΈ μλλ°©μ μ 보λ₯Ό κ°μ Έμ¬ μ μλ€
UDP μμλ νλμ μλ²λ§ ν΅μ νλ κ²½μ°λΌλ©΄ connect() ν¨μλ₯Ό μ΄μ©ν΄μ μλ²μ μ μν ν, μ§μ λ μ£Όμμ read()λ write() ν¨μλ₯Ό ν΅ν΄ ν΅μ μ μνν μ μλ€
sendto() ν¨μλ recvfrom() ν¨μλ€μ λ°μ΄ν°λ₯Ό μ£Όκ³ λ°μ λ λ€νΈμν¬λ₯Ό μ°κ²°νκ³ μ²λ¦¬κ° λλλ©΄ μ°κ²°λ λ€νΈμν¬λ λμ΄μ§λ€
connect() λ₯Ό μ΄μ©νλ©΄ λ€νΈμν¬μ μ°κ²°μ κ³μ μ μ§νκΈ° λλ¬Έμ λΉ λ₯Έ μλλ‘ μ 곡ν μ μλ€
β λ°μ΄νΈ μ‘°μ
λ€νΈμν¬ νλ‘κ·Έλλ―Έμμλ IPμ£Όμλ κΈ°ν μ²λ¦¬λ₯Ό μν΄ λ°μ΄νΈ μ‘°μμ΄ νμν κ²½μ°κ° λ§λ€
λ°μ΄νΈ μ‘°μμ μν΄ memset(), memcpy(), memcmp() λ±μ ν¨μκ° μ 곡λλ©°
BSD μ λμ€μμ bzero(), bcopy(), bcmp() λ±μ ν¨μλ₯Ό μ 곡νλ€
memset() ν¨μλ λ©λͺ¨λ¦¬μ λ°μ΄νΈλ₯Ό νΉμ κ°μΌλ‘ μ€μ ν μ μμ§λ§
λ€νΈμν¬ μ£Όμμ μ΄κΈ°νλ μ£Όλ‘ bzero() ν¨μλ₯Ό μ¬μ©ν΄μ λ°μ΄νΈλ₯Ό λͺ¨λ 0μΌλ‘ μ€μ νλ€
// udp_server.c
// μμΌμ μ΄μ©ν΄μ UDPλ‘ μλ‘ ν΅μ νκΈ°
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define UDP_PORT 5100
int main(int argc, char **argv)
{
int sockfd,n;
struct sockaddr_in servaddr, cliaddr;
socklen_t len;
char mesg[1000];
sockfd = socket(AF_INET, SOCK_DGRAM, 0); /* UDPλ₯Ό μν μμΌ μμ± */
/* μ μλλ ν΄λΌμ΄μΈνΈλ₯Ό μν μ£Όμ μ€μ ν μ΄μ체μ μ μλΉμ€ λ±λ‘ */
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(UDP_PORT);
bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
/* ν΄λΌμ΄μΈνΈλ‘λΆν° λ©μμ§λ₯Ό λ°μμ λ€μ ν΄λΌμ΄μΈνΈλ‘ μ μ‘ */
do {
len = sizeof(cliaddr);
n = recvfrom(sockfd, mesg, 1000, 0, (struct sockaddr *)&cliaddr, &len);
sendto(sockfd, mesg, n, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
mesg[n] = '\0';
printf("Received data : %s\n", mesg);
} while(strncmp(mesg, "q", 1));
close(sockfd); /* μ¬μ©μ΄ λλ ν μμΌ λ«κΈ° */
return 0;
}
/*
μλ²λ ν΄λΌμ΄μΈνΈλ‘λΆν° λ°μ΄ν°λ₯Ό λ°μμ κ·Έλλ‘ λ€μ λλλ €μ£Όλ μμ½ (ECHO) μλ²
socket() ν¨μμ SOCK_DGRAM μ΅μ
μ μ¬μ©ν΄μ UDPλ₯Ό μν μμΌμ νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ°λ€
ν΄λΉ νλ‘κ·Έλ¨μ μλ²λ‘ μ¬μ©νκΈ° μν΄μλ μ΄μ체μ μ μλΉμ€λ₯Ό λ±λ‘ν΄μΌ νλ€ -> bind()
bind() ν¨μμ sockaddr_in ꡬ쑰체λ₯Ό μ¬μ©ν΄μ μλ²μ μ£Όμμ ν¬νΈ λ²νΈλ₯Ό μ€μ νλ€
μ€μ νκΈ° μ μ sockaddr_in ꡬ쑰체λ₯Ό memset() ν¨μλ₯Ό ν΅ν΄ 0μΌλ‘ μ΄κΈ°ν
μλ²μ μ£Όμκ° λμ μΌλ‘ λ°κ·λλΌλ μ¬μ©νκΈ° μ½λλ‘ INADDR_ANY μ¬μ©
htonl() μ htons() ν¨μλ₯Ό μ΄μ©ν΄μ IP μ£Όμμ ν¬νΈ λ²νΈλ₯Ό λ€νΈμν¬ μμλ‘ μλμ λ³κ²½
루νλ¬Έ λλ©΄μ ν΄λΌμ΄μΈνΈλ‘λΆν° λ°μ΄ν°λ₯Ό λ°κ³ , λ°μ λ°μ΄ν°λ₯Ό sendto() ν¨μλ₯Ό μ΄μ©ν΄μ λ€μ ν΄λΌμ΄μΈνΈλ‘ μ μ‘
ν΄λΌμ΄μΈνΈμμ λ¬Έμμ΄ 'q' κ° μ€λ©΄ μ’
λ£, λͺ¨λ μμ
μ΄ λλλ©΄ close() ν¨μλ‘ μμΌ λ«κΈ°
*/
// udp_client.c
// μμΌμ μ΄μ©ν΄μ UDPλ‘ μλ‘ ν΅μ νκΈ°
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define UDP_PORT 5100
int main(int argc, char **argv)
{
int sockfd, n;
socklen_t clisize;
struct sockaddr_in servaddr, cliaddr;
char mesg[BUFSIZ];
if(argc != 2) {
printf("usage : %s <IP address>\n", argv[0]);
return -1;
}
sockfd = socket(AF_INET, SOCK_DGRAM, 0); /* UDPλ₯Ό μν μμΌ μμ± */
/* μλ²μ μ£Όμμ ν¬νΈ λ²νΈλ₯Ό μ΄μ©ν΄μ μ£Όμ μ€μ */
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
/* λ¬Έμμ΄μ λ€νΈμν¬ μ£Όμλ‘ λ³κ²½ */
inet_pton(AF_INET, argv[1], &(servaddr.sin_addr.s_addr));
servaddr.sin_port = htons(UDP_PORT);
/* ν€λ³΄λλ‘λΆν° λ¬Έμμ΄μ μ
λ ₯λ°μ μλ²λ‘ μ μ‘ */
do {
fgets(mesg, BUFSIZ, stdin);
sendto(sockfd, mesg, strlen(mesg), 0, (struct sockaddr *)&servaddr,
sizeof(servaddr));
clisize = sizeof(cliaddr);
/* μλ²λ‘λΆν° λ°μ΄ν°λ₯Ό λ°μμ νλ©΄μ μΆλ ₯ */
n = recvfrom(sockfd, mesg, BUFSIZ, 0, (struct sockaddr*) &cliaddr, &clisize);
mesg[n] = '\0';
fputs(mesg, stdout);
} while(strncmp(mesg, "q", 1));
close(sockfd);
return 0;
}
/*
νλ‘κ·Έλ¨μ μ«λν λ μ μν μλ²μ μ£Όμλ₯Ό μ
λ ₯νλ©΄ λλλ°
μ
λ ₯λ°μ λ¬Έμλ inet_pton() ν¨μλ₯Ό μ΄μ©ν΄μ 16μ§μ μ£Όμλ‘ λ³νν μ μλ€
λΌμ¦λ² 리νμ΄λ‘ μ μμ€μ΄λΌλ©΄ μλ²λ₯Ό λ°±κ·ΈλΌμ΄λ λͺ¨λλ‘ μ€ννλ€ &
κ°μ λΌμ¦λ² 리νμ΄ μμμ UDP μλ²μ ν΄λΌμ΄μΈνΈλ₯Ό ν¨κ» μ€νν λ μλ² μ£Όμλ‘ 127.0.0.1
127.0.0.1μ 루νλ°± μ£ΌμλΌκ³ λ νλλ°, νμ¬ μμ€ν
μ체μ IP μ£Όμλ₯Ό μ§μΉν λ μ¬μ©νλ€
ν΄λΌμ΄μΈνΈμμ λ¬Έμμ΄μ μ
λ ₯νλ©΄ UDPλ₯Ό ν΅ν΄ ν΄λΌμ΄μΈνΈμ μλ² κ° ν΅μ μ΄ μ΄λ€μ§λ€
μλ²λ μ΄μ체μ μμ λμ΄μ¨ λ°μ΄ν°λ₯Ό λ°μμ νλ©΄μ μΆλ ₯ν λ€ λ°λ‘ μΆλ ₯νκ³
λ€μ ν΄λΌμ΄μΈνΈμ μ
λ ₯μ κΈ°λ€λ¦°λ€
*/
gcc -o udp_server udp_server.c
gcc -o udp_client udp_client.c
./udp_server &
./udp_client 127.0.0.1