Socket_2


Socket_2: DNS 서버 시뮬레이터


프로그램 설명

이 프로그램은 도메인 이름과 IP 주소 간의 매핑 정보를 처리하는 간단 DNS(Domain Name System) 서버 시뮬레이터이다.
실제 DNS 서버처럼, 클라이언트는 도메인 이름을 서버에 요청하고, 서버는 그에 해당하는 IP 주소를 반환한다. 또한 클라이언트가 새로운 도메인-IP 매핑 정보를 등록할 수도 있으며, 이 정보는 서버의 데이터베이스(SQLite)에 저장된다.


소스 프로그램

[1] dns_server_db.py서버 코드 (SQLite DB 사용)

import socket
import sqlite3

# 데이터베이스 연결 및 테이블 생성
conn = sqlite3.connect("dns.db", check_same_thread=False)
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS dns_table (
    domain TEXT PRIMARY KEY,
    ip TEXT
)
""")
conn.commit()

HOST = '127.0.0.1'
PORT = 9999

# TCP 서버 소켓 설정
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen(1)
print(f"[DNS 서버] {HOST}:{PORT} 에서 실행 중...")

while True:
    client_socket, addr = server_socket.accept()
    print(f"[접속] 클라이언트: {addr}")

    while True:
        try:
            data = client_socket.recv(1024).decode()
            if not data:
                break

            tokens = data.strip().split()

            if tokens[0] == 'r':  # 조회
                if len(tokens) != 2:
                    response = "[ERROR] r 명령어 형식: r 도메인"
                else:
                    domain = tokens[1]
                    cursor.execute("SELECT ip FROM dns_table WHERE domain = ?", (domain,))
                    row = cursor.fetchone()
                    if row:
                        response = f"{domain} → {row[0]}"
                    else:
                        response = f"[ERROR] {domain} not found."

            elif tokens[0] == 'w':  # 등록
                if len(tokens) != 3:
                    response = "[ERROR] w 명령어 형식: w 도메인 IP주소"
                else:
                    domain, ip = tokens[1], tokens[2]
                    cursor.execute("INSERT OR REPLACE INTO dns_table (domain, ip) VALUES (?, ?)", (domain, ip))
                    conn.commit()
                    response = f"[OK] {domain} → {ip} 등록 완료."

            else:
                response = "[ERROR] 알 수 없는 명령어입니다. r 또는 w 사용."

            client_socket.sendall(response.encode())

        except ConnectionResetError:
            break

    client_socket.close()
    print(f"[종료] 클라이언트: {addr}")

[2] dns_client.py클라이언트 코드

import socket

HOST = '127.0.0.1'
PORT = 9999

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client_socket:
    client_socket.connect((HOST, PORT))
    print("[클라이언트] DNS 서버에 연결되었습니다. (종료하려면 'exit' 입력)")

    while True:
        cmd = input("명령 입력 (예: r google.com / w mysite.com 192.168.0.10): ").strip()
        if cmd == 'exit':
            break
        client_socket.sendall(cmd.encode())

        data = client_socket.recv(1024).decode()
        print(f"[서버 응답] {data}")

실행 방법 요약

  1. 두 파일을 같은 폴더에 저장
  2. 터미널 2개 실행

클라이언트에서 명령 입력 예시:

w example.com 8.8.8.8
r example.com

다른 하나는 클라이언트 실행:

python dns_client.py

하나는 서버 실행:

python dns_server_db.py

DB에 저장되는 DNS 서버 구축 완료.


dns_server_db.py 코드 설명

이 코드는 클라이언트로부터 도메인 조회(r) 또는 등록(w) 요청을 받아 처리하고, 도메인-IP 매핑 정보를 SQLite 데이터베이스에 저장하는 DNS 서버 역할을 한다.

주요 구성

1. SQLite 연결 및 테이블 생성

conn = sqlite3.connect("dns.db", check_same_thread=False)
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS dns_table (
    domain TEXT PRIMARY KEY,
    ip TEXT
)
""")
  • dns.db라는 이름의 데이터베이스 파일을 생성 (또는 연결)
  • dns_table이라는 테이블을 만들고 domainip 저장
  • domain은 중복 불가능한 기본 키(Primary Key)

2. 서버 소켓 생성 및 바인딩

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen(1)
  • TCP 통신용 소켓 생성
  • 127.0.0.1(로컬호스트)와 포트 9999에 바인딩
  • 클라이언트 접속 대기 상태로 전환

3. 클라이언트 접속 수락 및 통신 처리

client_socket, addr = server_socket.accept()
  • 클라이언트가 접속하면 연결 수락하고 client_socket 생성

4. 명령어 처리

data = client_socket.recv(1024).decode()
tokens = data.strip().split()
  • 클라이언트가 보낸 메시지를 받아서 공백 기준으로 분해
r 도메인 요청
cursor.execute("SELECT ip FROM dns_table WHERE domain = ?", (domain,))
  • 데이터베이스에서 해당 도메인을 조회
  • 있으면 IP 응답, 없으면 에러 메시지
w 도메인 IP주소 요청
cursor.execute("INSERT OR REPLACE INTO dns_table (domain, ip) VALUES (?, ?)", (domain, ip))
  • 도메인을 등록하거나 기존 것을 업데이트
  • DB에 즉시 반영: conn.commit()

5. 응답 전송

client_socket.sendall(response.encode())
  • 서버가 처리 결과를 클라이언트에게 문자열 형태로 전송

6. 연결 종료 처리

client_socket.close()
  • 통신 종료 시 소켓 닫기

dns_client.py 코드 설명

이 코드는 사용자로부터 명령어를 입력받아 서버에 전송하고, 응답 결과를 출력하는 클라이언트 역할을 한다.

주요 구성

1. 서버에 접속

client_socket.connect((HOST, PORT))
  • 서버(IP 127.0.0.1, 포트 9999)에 연결

2. 명령어 입력 및 전송

cmd = input("명령 입력 ...")
client_socket.sendall(cmd.encode())
  • 사용자 입력을 받아 서버로 전송 (r 도메인, w 도메인 IP)

3. 응답 수신 및 출력

data = client_socket.recv(1024).decode()
print(f"[서버 응답] {data}")
  • 서버로부터 받은 메시지를 화면에 출력

4. 종료 명령

if cmd == 'exit':
    break
  • 사용자가 exit를 입력하면 프로그램 종료

출력 내용 + 입력 내용

서버 측 출력:

클라이언트 측 출력:

DB 확인:


Read more

Socket_1

Socket_1: 문자열을 아스키코드로 변환하는 소켓 프로그래밍 프로그램 설명 이 프로그램은 TCP 소켓을 이용하여 클라이언트가 전송한 문자열을 서버가 받아, 해당 문자열을 아스키코드 리스트로 변환한 뒤, 다시 클라이언트에게 전송하는 방식으로 작동한다. 양방향 통신은 문자열 기반이며, 서버는 수신한 문자열을 각 문자마다 ord()를 통해 아스키 코드로 바꾼다. * 통신 방식: TCP * 인코딩 방식:

By Youn

네트워크_Mobility

Mobility란? Mobility(이동성)은 네트워크에서 기기가 네트워크 위치(IP 주소 등)가 바뀌더라도 지속적으로 연결을 유지할 수 있는 능력을 말합니다. Mobility를 처리하는 두 가지 접근 방식 1. Routing이 Mobility를 처리하게 한다 (Network-based mobility) * 개념: 이동하는 호스트의 현재 위치를 네트워크가 추적하고, 그에 따라 패킷 경로를 동적으로 수정함 * 예시: Mobile IP * 홈

By Youn