소켓이란?
소켓은 프로그램과 운영 체제 간의 인터페이스 역할을 합니다. 프로그램에서 소켓 작업을 요청하면, 운영 체제는 그 요청을 받아들여 새로운 소켓을 생성합니다. 이 소켓을 통해서만 외부 네트워크와 통신할 수 있습니다.
비유로 설명하자면, 소켓은 프로그램 내부에서 "창구" 역할을 하며, 실제 통신은 소켓들 간에 이루어집니다. 예를 들어, 채팅 프로그램에서 우리가 메시지를 보내면, 실제로는 소켓을 통해 상대방에게 전달되고, 그 소켓을 통해 메시지가 받아지게 됩니다. 채팅 프로그램 자체는 외부 네트워크와 직접 통신하지 않습니다.
또한, 소켓은 양쪽 프로그램 간의 통신을 중개하는 역할을 합니다. 예를 들어, 소켓 A는 프로그램 1과 통신하고, 소켓 B는 프로그램 2와 통신하며, 소켓 A와 B는 서로 메시지를 주고받습니다.
이렇게 소켓 프로그래밍은 네트워크 프로그래밍을 위한 핵심 기술로, 소켓을 사용하여 서로 다른 호스트에 있는 프로세스 간에 통신할 수 있습니다. 주로 TCP/IP 프로토콜을 이용하여 양방향 통신을 지원합니다.
Python에서 소켓 프로그래밍 사용
Python에서는 소켓 프로그래밍을 위해 socket 모듈을 사용합니다.
이 모듈을 통해 소켓을 생성하고, 연결을 설정하고, 데이터를 송수신할 수 있습니다.
# 단순 서버: 접속 상태 확인용으로 1개의 접속만 처리
# 소켓 모듈에서 모든 함수와 상수를 불러옵니다.
from socket import *
# TCP/IP 프로토콜을 사용하는 스트림 소켓을 생성합니다.
serversock = socket(AF_INET, SOCK_STREAM)
# 서버 소켓을 특정 IP 주소와 포트에 바인딩합니다.
# 여기서는 127.0.0.1(로컬 호스트)의 8888번 포트를 사용합니다.
serversock.bind(('127.0.0.1', 8888))
# 서버 소켓을 리스닝 상태로 전환합니다.
# 이 경우에는 동시에 1개의 클라이언트만을 대기합니다.
serversock.listen(1)
# 서버가 서비스 중임을 알리는 메시지를 출력합니다.
print('서버 서비스 중 ...')
# 클라이언트의 연결을 기다리고, 연결이 수락되면 클라이언트와 통신하기 위한 새로운 소켓 객체와 클라이언트의 주소를 반환합니다.
conn, addr = serversock.accept()
# 클라이언트의 주소를 출력합니다.
print('client addr: ', addr)
# 클라이언트로부터 메시지를 받아서 출력합니다.
# conn.recv(1024)는 최대 1024바이트의 데이터를 수신하며, decode() 메서드를 사용하여 바이트 데이터를 문자열로 변환합니다.
print('from client message:', conn.recv(1024).decode())
# 클라이언트와의 연결을 닫습니다.
conn.close()
# 서버 소켓을 닫습니다.
serversock.close()
단일 연결 서버
# 단순 클라이언트
# 소켓 모듈에서 모든 함수와 상수를 불러옵니다.
from socket import *
# TCP/IP 프로토콜을 사용하는 스트림 소켓을 생성합니다.
clientsock = socket(AF_INET, SOCK_STREAM)
# 서버에 연결합니다. 여기서는 127.0.0.1(로컬 호스트)의 8888번 포트로 연결합니다.
clientsock.connect(('127.0.0.1', 8888))
# 서버로 메시지를 보냅니다. 문자열을 바이트로 변환하여 보냅니다.
# '안녕 반가워'라는 문자열을 utf-8 형식으로 인코딩한 후 보냅니다.
clientsock.send('안녕 반가워'.encode(encoding='utf_8', errors='strict'))
# 클라이언트 소켓을 닫습니다.
clientsock.close()
단순 클라이언트-서버에 연결, 메세지 전송 및 연결 닫기