티스토리 뷰
안녕하세요.
신랑 각시의 신랑입니다.
일하면서, IPv4 와 IPv6 Client 를 연결 요청을 모두 받아야 하는 Server 가 필요했는데요, IPv6 용 Server 를 만들어 두면 모두 수용 가능합니다.
배경 적인 내용은 검색하시거나 책을 찾아보시면 좋을 것 같구요.
제 블로그에서는 IPv6 용 Server 소스만 적어볼까 합니다.
아래는 소스 전체와 컴파일 Line 입니다.
#include
#include #include #include #include #include #include std::string GetPeerInfo(struct sockaddr * _addr, socklen_t _addrlen) { char hostname[256]; char svcname[64]; if(getnameinfo(_addr, _addrlen, hostname, sizeof(hostname), svcname, sizeof(svcname), NI_NUMERICHOST | NI_NUMERICSERV) != 0) { char buf[128]; std::cout << "getnameinfo() - fail " << errno << ":" << strerror_r(errno, buf, sizeof(buf)); std::cout << std::endl; return ""; } return std::string(hostname) + ":" + svcname; } void doServer(int _sock) { if(listen(_sock, 5) < 0) { std::cout << "[SERVER] listen() fail : " << strerror(errno) << std::endl; return ; } struct sockaddr clientaddr; socklen_t addrlen; while(true) { std::cout << "[SERVER] accept() wait" << std::endl; int conn = accept(_sock, &clientaddr, &addrlen); if(conn < 0) { std::cout << "[SERVER] accept() fail : " << strerror(errno) << std::endl; continue; } else { std::cout << "[SERVER] connected from : " << GetPeerInfo(&clientaddr, addrlen) << std::endl; } char cBuf; while(true) { if(recv(conn, &cBuf, 1, 0) <= 0) break; std::cout << cBuf; if(send(conn, &cBuf, 1, 0) <= 0) break; } std::cout << std::endl; close(conn); } close(_sock); std::cout << "[SERVER] Bye" << std::endl; } void serverIPv6(char * _port) { std::cout << "[SERVER] IPv6 Only Mode" << std::endl; int sfd = socket(AF_INET6, SOCK_STREAM, 0); if(sfd < 0) { std::cout << "socket() fail : " << strerror(errno) << std::endl; return ; } int on = 1; setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); struct sockaddr_in6 addr; addr.sin6_family = AF_INET6; addr.sin6_port = htons(std::stoi(_port)); addr.sin6_addr = in6addr_any; if(bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { std::cout << "bind() fail : " << strerror(errno) << std::endl; close(sfd); return ; } doServer(sfd); close(sfd); } int main(int argc, char * argv[]) { if(argc != 2) { std::cout << "invalid argument" << std::endl; std::cout << "ex) server6 [port]" << std::endl; return 0; } serverIPv6(argv[1]); return 0; }
몇 가지 설명을 하자면,
1) Peer 주소를 알기 위하여 IPv4 와 IPv6 를 모두 표현할 수 있는 getnameinfo() 함수를 사용했습니다.
2) doServer() 함수에서 listen() 과 accept() 를 호출하고, 끊어질 때까지 echo 서버로 동작합니다.
3) serverIPv6() 함수에서 socket() 과 bind() 를 호출한 뒤에, doServer() 를 호출합니다.
위의 코드를 server6.cpp 파일에 넣고, 아래와 같이 컴파일 했습니다.
g++ -o server6 -std=c++11
테스트 결과는 클라이언트 소스를 쓰고 난 뒤에 포스팅 하도록 하겠습니다.
'일하면서' 카테고리의 다른 글
[Short Code] IPv6 socket code (3/3) - Test (0) | 2018.05.24 |
---|---|
[Short Code] IPv6 socket code (2/3) - Dual Client (0) | 2018.05.21 |
[short code] 8 byte endian 변환 (0) | 2017.12.26 |
[short code] 반복적인 ftp 작업을 one command 로 (0) | 2017.12.11 |
[short code] BCD encoding (0) | 2017.12.05 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 8byte endian 변환
- forwarding
- ipv6 socket program
- sftp 자동접속
- ftp 자동접속 스크립트
- BCD 변환
- ssh key 만들기
- IPv6 client
- ftp 자동접속
- IPv4 and IPv6
- 엔디안 변환
- 엔디안
- client socket
- IPv6
- IPv6 socket
- IPv6 echo server
- ssh key
- IPv6 IPv4 Dual client
- socket program
- endian
- std:map
- ftp 스크립트
- 서버 경유
- c++
- IPv6 server
- remove
- short code
- endian 변환
- FTW
- 8 byte 엔디안 변환
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
글 보관함