반응형
UDP 소켓 프로그래밍
UDP(User Datagram Protocol)는 비연결형 프로토콜로, 신뢰성보다는 빠른 데이터 전송을 목적으로 합니다. UDP는 데이터의 순서나 무결성을 보장하지 않기 때문에, 주로 실시간 스트리밍, 게임 네트워크, 간단한 요청-응답 등의 용도로 사용됩니다.
UDP 소켓 프로그래밍의 주요 함수
소켓 생성
- socket() 함수: 소켓을 생성합니다.
- domain: 주소 체계 (예: AF_INET - IPv4)
- type: 소켓 타입 (예: SOCK_DGRAM - UDP)
- protocol: 프로토콜 (일반적으로 0으로 설정)
int socket(int domain, int type, int protocol);
서버 측 소켓 프로그래밍
- bind() 함수: 소켓에 IP 주소와 포트 번호를 바인딩합니다.
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
- recvfrom() 함수: 데이터를 수신합니다.
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
- sendto() 함수: 데이터를 전송합니다.
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
클라이언트 측 소켓 프로그래밍
- sendto() 함수: 데이터를 전송합니다.
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
- recvfrom() 함수: 데이터를 수신합니다.
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
UDP 서버 구현
UDP 서버 코드 예제
#include <iostream>
#include <boost/asio.hpp>
using boost::asio::ip::udp;
int main() {
try {
// io_context 객체 생성
boost::asio::io_context io_context;
// UDP 수신자 생성, 포트 12345에서 수신 대기
udp::socket socket(io_context, udp::endpoint(udp::v4(), 12345));
std::cout << "UDP 서버가 포트 12345에서 대기 중입니다..." << std::endl;
while (true) {
char data[1024];
udp::endpoint sender_endpoint;
boost::system::error_code error;
// 클라이언트로부터 데이터 수신
size_t length = socket.receive_from(boost::asio::buffer(data), sender_endpoint, 0, error);
if (error && error != boost::asio::error::message_size) {
throw boost::system::system_error(error);
}
std::cout << "수신한 메시지: " << std::string(data, length) << std::endl;
// 클라이언트에게 수신한 메시지 그대로 전송 (에코)
socket.send_to(boost::asio::buffer(data, length), sender_endpoint, 0, error);
}
} catch (std::exception& e) {
std::cerr << "예외 발생: " << e.what() << std::endl;
}
return 0;
}
UDP 클라이언트 구현
UDP 클라이언트 코드 예제
#include <iostream>
#include <boost/asio.hpp>
using boost::asio::ip::udp;
int main() {
try {
// io_context 객체 생성
boost::asio::io_context io_context;
// UDP 소켓 생성
udp::socket socket(io_context);
// 서버의 엔드포인트 생성
udp::endpoint server_endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 12345);
// 사용자로부터 입력받은 메시지를 서버로 전송하고, 에코된 메시지를 수신
std::string message;
while (std::getline(std::cin, message)) {
message += "\n";
boost::system::error_code error;
// 서버로 메시지 전송
socket.send_to(boost::asio::buffer(message), server_endpoint, 0, error);
char data[1024];
udp::endpoint sender_endpoint;
// 서버로부터 에코된 메시지 수신
size_t length = socket.receive_from(boost::asio::buffer(data), sender_endpoint, 0, error);
std::cout << "서버로부터 에코된 메시지: " << std::string(data, length) << std::endl;
}
} catch (std::exception& e) {
std::cerr << "예외 발생: " << e.what() << std::endl;
}
return 0;
}
설명
위의 코드는 간단한 UDP 에코 서버와 클라이언트를 구현한 예제입니다. 클라이언트는 사용자가 입력한 메시지를 서버로 전송하고, 서버는 수신한 메시지를 다시 클라이언트로 전송합니다.
- UDP 에코 서버:
- 서버는
udp::socket
을 사용하여 포트 12345에서 데이터그램을 수신합니다. - 클라이언트로부터 데이터를 수신한 후, 동일한 데이터를 다시 클라이언트로 전송합니다.
- 서버는
- UDP 에코 클라이언트:
- 클라이언트는
udp::socket
을 사용하여 서버의 엔드포인트로 데이터그램을 전송합니다. - 서버로부터 에코된 메시지를 수신하여 출력합니다.
- 클라이언트는
실습 문제
문제 1: 간단한 에코 서버와 클라이언트 작성하기
TCP 에코 서버와 클라이언트를 작성하여, 클라이언트가 보낸 메시지를 서버가 다시 클라이언트에게 보내도록 구현하세요.
해설:
UDP 에코 서버
#include <iostream>
#include <boost/asio.hpp>
using boost::asio::ip::udp;
int main() {
try {
// io_context 객체 생성
boost::asio::io_context io_context;
// UDP 수신자 생성, 포트 12345에서 수신 대기
udp::socket socket(io_context, udp::endpoint(udp::v4(), 12345));
std::cout << "UDP 서버가 포트 12345에서 대기 중입니다..." << std::endl;
while (true) {
char data[1024];
udp::endpoint sender_endpoint;
boost::system::error_code error;
// 클라이언트로부터 데이터 수신
size_t length = socket.receive_from(boost::asio::buffer(data), sender_endpoint, 0, error);
if (error && error != boost::asio::error::message_size) {
throw boost::system::system_error(error);
}
std::cout << "수신한 메시지: " << std::string(data, length) << std::endl;
// 클라이언트에게 수신한 메시지 그대로 전송 (에코)
socket.send_to(boost::asio::buffer(data, length), sender_endpoint, 0, error);
}
} catch (std::exception& e) {
std::cerr << "예외 발생: " << e.what() << std::endl;
}
return 0;
}
UDP 에코 클라이언트
#include <iostream>
#include <boost/asio.hpp>
using boost::asio::ip::udp;
int main() {
try {
// io_context 객체 생성
boost::asio::io_context io_context;
// UDP 소켓 생성
udp::socket socket(io_context);
// 서버의 엔드포인트 생성
udp::endpoint server_endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 12345);
// 사용자로부터 입력받은 메시지를 서버로 전송하고, 에코된 메시지를 수신
std::string message;
while (std::getline(std::cin, message)) {
message += "\n";
boost::system::error_code error;
// 서버로 메시지 전송
socket.send_to(boost::asio::buffer(message), server_endpoint, 0, error);
char data[1024];
udp::endpoint sender_endpoint;
// 서버로부터 에코된 메시지 수신
size_t length = socket.receive_from(boost::asio::buffer(data), sender_endpoint, 0, error);
std::cout << "서버로부터 에코된 메시지: " << std::string(data, length) << std::endl;
}
} catch (std::exception& e) {
std::cerr << "예외 발생: " << e.what() << std::endl;
}
return
0;
}
이제 세 번째 날의 학습을 마쳤습니다. UDP 소켓 프로그래밍의 기본 개념과 구현 방법을 학습했습니다.
질문이나 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "비동기 소켓 프로그래밍"에 대해 학습하겠습니다.
반응형
'-----ETC----- > C++ 네트워크 프로그래밍 시리즈' 카테고리의 다른 글
[C++ 네트워크 프로그래밍] Day 5: 네트워크 데이터 직렬화 (0) | 2024.08.01 |
---|---|
[C++ 네트워크 프로그래밍] Day 6: 네트워크 프로토콜 기초 (0) | 2024.08.01 |
[C++ 네트워크 프로그래밍] Day 4: 비동기 소켓 프로그래밍 (0) | 2024.08.01 |
[C++ 네트워크 프로그래밍] Day 2: 소켓 프로그래밍 기초 (TCP) (0) | 2024.08.01 |
[C++ 네트워크 프로그래밍 ] Day 1: 네트워크 프로그래밍 소개와 개발 환경 설정 (0) | 2024.08.01 |