파이썬으로 네트워크 프로그램을 하기 위해서는 라이브러리를 가져와야 해야 합니다. (import)
기본이 되는 socket 모듈을 가져와서 네트워크 프로그램을 시작해보겠습니다.
소켓은 네트워크에서 서버에 접속할 때 사용하는 그 소켓입니다.
socket 은 파이썬 기본 패키지에 포함된 내장 모듈입니다.
import socket
host = socket.gethostname()
ipAddress = socket.gethostbyname(host)
print("Host name:", host)
print("IP Address:", ipAddress)
Host name: DESKTOP-2HF
IP Address: 127.0.1.1
Host name은 현재 호스트 장치의 이름입니다.
IP Address 는 호스트의 주소를 가져옵니다. 여기서는 로컬PC를 말하는 겁니다.
도메인 네임만 알면 호스트 IP의 정보를 가져올 수 있습니다.
import socket
remote_host1 = 'blog.naver.com'
remote_host2 = 'www.daum.net'
print("네이버블로그:", socket.gethostbyname(remote_host1))
print("다음:", socket.gethostbyname(remote_host2))
네이버블로그: 210.89.160.53
다음: 203.133.167.81
네이버나 다음의 IP주소도 일정 시간마다 변합니다.
import socket
remote_host1 = 'blog.naver.com'
ipAddress1 = socket.gethostbyname(remote_host1)
packedIp = socket.inet_aton(ipAddress1)
unpackedIp = socket.inet_ntoa(packedIp)
print(">> 네이버블로그 IP: %s" % ipAddress1)
print(">> Packed IP : %s" % packedIp)
print(">> Unpacked IP : %s" % unpackedIp)
>> 네이버블로그 IP: 210.89.160.53
>> Packed IP : b'\xd2Y\xa05'
>> Unpacked IP : 210.89.160.53
IP주소는 문자열로 표시되는데 이는 네트워크에 운송하기에는 적합하지 않습니다. socket의 메소드 inet_aton 을 사용하여 IP정보를 32bit 바이트로 변환합니다.
문자열로 표시해야 할 때는 메소드 inet_ntoa 를 사용하여 unpacked 할 수 있습니다. 마치 택배를 보내기 위해 포장작업을 하는 것과 비슷합니다.
서버의 포트에 접속해서 포트에 걸려있는 서비스 이름을 가져옵니다.
예제는 0에서 99까지 포트를 확인해 봅니다. 보통 웹에서 사용하는 포트는 80입니다.
for i in range(100):
try:
serviceTcp = socket.getservbyport(i, 'tcp')
print("\nport number:", i, end=' ')
print('(tcp)', serviceTcp, end=' ')
except:
pass
try:
serviceUdp = socket.getservbyport(i, 'udp')
print("\nport number:", i, end =' ')
print('(udp)', serviceUdp, end= ' ')
except:
pass
port number: 7 (tcp) echo
port number: 7 (udp) echo
port number: 9 (tcp) discard
port number: 9 (udp) discard
port number: 11 (tcp) systat
port number: 11 (udp) systat
port number: 13 (tcp) daytime
port number: 13 (udp) daytime
port number: 17 (tcp) qotd
port number: 17 (udp) qotd
port number: 19 (tcp) chargen
port number: 19 (udp) chargen
port number: 20 (tcp) ftp-data
port number: 21 (tcp) ftp
port number: 22 (tcp) ssh
port number: 23 (tcp) telnet
port number: 25 (tcp) smtp
port number: 37 (tcp) time
port number: 37 (udp) time
port number: 39 (udp) rlp
port number: 42 (tcp) nameserver
port number: 42 (udp) nameserver
port number: 43 (tcp) nicname
port number: 53 (tcp) domain
port number: 53 (udp) domain
port number: 67 (udp) bootps
port number: 68 (udp) bootpc
port number: 69 (udp) tftp
port number: 70 (tcp) gopher
port number: 79 (tcp) finger
port number: 80 (tcp) http
port number: 81 (tcp) hosts2-ns
port number: 81 (udp) hosts2-ns
port number: 88 (tcp) kerberos
port number: 88 (udp) kerberos
정수 1234를 32비트와 16비트로 변환합니다.
숫자를 변환한다는게 좀 귀찮은 일이 되겠지만 파이썬의 정수형과 네트워크에 운반하는 형태가 다르기 때문입니다
아래 메소드의 n은 network h는 host, l은 long s는 short 을 의미합니다.
data = 1234
# 32 bit
print()
print(socket.ntohl(data))
print(socket.htonl(data))
# 16 bit
print(socket.ntohs(data))
print(socket.htons(data))
3523477504
3523477504
53764
53764
소켓 타임아웃은 클라이언트가 서버의 응답을 대기하는 시간이라 보면 됩니다.
서버의 상태가 제대로 응답하기 힘든 상태라고 해서 클라이언트가 무작정 기다릴 수 없기 때문에 타임아웃(시간끝)을 설정합니다. Default 는 설정이 없습니다.
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Default timeout:", s1.gettimeout())
s1.settimeout(100)
print("Current timeout:", s1.gettimeout())
Default timeout: None
Current timeout: 100.0