UDT통신으로 데이터를 받을 때, C++ 언어로 소켓을 열고 프린트 하는 방법에 대해 알아보자
필요한 것은 크게 3가지이다.
통신 포트 넘버
, 컴퓨터의 IP주소
, 버퍼의 최대 크기
이다.
먼저 위의 라이브러리들을 include 해주자.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
위의 라이브러리들은 따로 빌드를 해주거나, CMakeLists.txt
에서 따로 타겟 링크나 인클루드 디렉토리를 신경써줄 필요없다.
그 다음 바로 메인 문으로 들어가보자.
#define BUFSIZE 512
int main(int argc, char* argv[]) {
// socket() 생성
int sock=socket(AF_INET, SOCK_DGRAM, 0); //(주소 체계, 소켓 타입, 프로토콜)
int retval;
// bind() 소켓에 주소 할당
sockaddr_in serveraddr;
bzero(&serveraddr, sizeof(serveraddr)); //0으로 초기화
serveraddr.sin_family=AF_INET; // IPv4 인터넷 프로토롤
serveraddr.sin_port=htons(포트 번호);
serveraddr.sin_addr.s_addr=inet_addr("내 IP 주소");
retval=bind(sock, (sockaddr*)&serveraddr, sizeof(serveraddr));
// 데이터 통신에 사용할 변수
sockaddr_in clientaddr;
int addrlen;
char buf[BUFSIZE+1];
// 클라이언트와 데이터 통신
while (true) {
// 데이터 받기
addrlen = sizeof(clientaddr);
retval = recvfrom(sock,buf,BUFSIZE,0,(sockaddr*)&clientaddr, (socklen_t*)&addrlen);
//받은 데이터 출력
buf[retval]='\0';
std::cout << "[UDP/"<<inet_ntoa(clientaddr.sin_addr) << " : " << ntohs(clientaddr.sin_port) << "]\n";
print_HEX(buf, retval);
std::cout << std::endl;
}
// 클라이언트 소켓 연결 종료
close(sock);
return 0;
}
받은 데이터는 char
배열의 버퍼로 받았으니, 출력을 해서 데이터가 잘 들어왔는지 확인이 필요하다.
void print_HEX(const char buf[], const int retval) {
for (int i = 0; i < retval; ++i) {
printf("0x%02X ", buf[i]);
if (i == 4) {
std::cout << "\n";
}
if ((i - 4) % 13 == 0 && i != 4) {
std::cout << "\n";
}
}
}
최대 버퍼의 크기는 데이터를 쏴주는 곳에서 확인이 가능하며, 매번 들어오는 버퍼의 크기는 항상 최대 크기보다 작다. 이때 얼마만큼 알려주는 것이 retval
값이다.