2011-09-15 10 views
4

bash에서 일부 스크립트를 번역 할 때 우리 서비스 중 하나가 수신 중인지 찾기 위해 netstat -an을 여러 번 사용하고 있습니다. 내가 subprocess.call이나 다른 popen을 사용할 수 있다는 것을 알고는 있지만 python 해결책을 사용하고 있기 때문에 우리가 운영하는 유닉스 환경을 활용하지 않을 것이다.Python을 사용하여 청취 포트 확인

내가 읽었던 것은 소켓 모듈이 가지고 있어야하는 것이지만, 청취 포트를 확인하는 것을 본 적이 없습니다. 간단한 트릭을 이해하지 못하는 것일 수도 있지만, 지금까지 소켓에 연결하는 방법을 알고, 연결이 실패했을 때 알 수있는 것을 써주세요. 그러나 필자는 포트를 특별히 점검하여 무언가를 발견했는지 반드시 확인할 필요는 없습니다.

아이디어가 있으십니까?

+0

어떤 운영 체제입니까? – NPE

답변

9

어떻게 연결을 시도에 대한 ...

import socket 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
result = s.connect_ex(('127.0.0.1', 3306)) 

if result == 0: 
    print('socket is open') 
s.close() 
+0

나는 이것이 충분하다고 생각하지 않는다.그것은 * 무언가 * 듣고 있지만 아무것도 될 수 있습니다, 반드시 당신이 기대하는 과정이 아니라는 것을 알려줍니다. – richardw

+1

richardw 어떻게 정교하게 작성 하시겠습니까? –

2

당신은 문제의 포트에 연결을 시도, 또는 netstat을 에뮬레이션 할 수 중 하나.

후자를 수행하는 것은 OS에 따라 다릅니다. Linux에서는 /proc/net/tcp을 검사 할 수 있습니다. 그것은 다음과 같습니다 : 당신은 st ("상태") 열에서 0A이 라인을 찾고

sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode              
    0: 00000000:C809 00000000:0000 0A 00000000:00000000 00:00000000 00000000 117  0 8381 1 ffff8802f22a8000 300 0 0 2 -1      
    1: 00000000:16CC 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1026  0 14336 1 ffff8802f2249440 300 0 0 2 -1      
    2: 00000000:006F 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0  0 7876 1 ffff8802f2248000 300 0 0 2 -1      
    3: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0  0 8163 1 ffff8802f3578000 300 0 0 2 -1      
    4: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0  0 981582 1 ffff8800d7a53600 300 0 0 2 -1      
    5: 00000000:0019 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0  0 9129 1 ffff8802edc886c0 300 0 0 2 -1      
    6: 00000000:021A 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0  0 9016 1 ffff8802edc88000 300 0 0 2 -1      
    7: 00000000:2B1C 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1026  0 783709 1 ffff8803119cca40 300 0 0 2 -1      
    8: 00000000:977C 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0  0 24292 1 ffff8802f224e540 300 0 0 2 -1      

. 콜론 뒤에있는 숫자는 local_address - C809, 16CC 등이며 수신 대기 프로세스가있는 TCP 포트 번호 (16 진수)입니다.

2

Linux에서는 strace를 사용하여 netstat -ln이 읽고 있고 /proc 파일 시스템에서 다양한 값을 파싱 할 수 있습니다.

$ strace netstat -ln 2>&1| grep '/proc' 
open("/proc/net/tcp", O_RDONLY)   = 3 
open("/proc/net/tcp6", O_RDONLY)  = 3 
open("/proc/net/udp", O_RDONLY)   = 3 
open("/proc/net/udp6", O_RDONLY)  = 3 
open("/proc/net/raw", O_RDONLY)   = 3 
open("/proc/net/raw6", O_RDONLY)  = 3 
open("/proc/net/unix", O_RDONLY)  = 3 
open("/proc/net/ipx/socket", O_RDONLY) = -1 ENOENT (No such file or directory) 
open("/proc/net/ipx", O_RDONLY)   = -1 ENOENT (No such file or directory) 
open("/proc/net/ax25", O_RDONLY)  = -1 ENOENT (No such file or directory) 
open("/proc/net/x25", O_RDONLY)   = -1 ENOENT (No such file or directory) 
open("/proc/net/x25", O_RDONLY)   = -1 ENOENT (No such file or directory) 
open("/proc/net/nr", O_RDONLY)   = -1 ENOENT (No such file or directory) 

그래서 당신은 파이썬에서 그 파일을 읽고 데이터 당신 필요성을 추출 할 수 있습니다. 0000

주소 :

$ cat /proc/net/tcp 
    sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode 
    0: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0  0 8190 1 00000000 300 0 0 2 -1 
    1: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0  0 6458 1 00000000 300 0 0 2 -1 
    2: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0  0 10425 1 00000000 300 0 0 2 -1 
    3: 8D0BA8C0:8801 689255D1:01BB 01 00000000:00000000 00:00000000 00000000 1000  0 1680975 1 00000000 24 4 16 6 -1 
    4: 8D0BA8C0:D142 97E67D4A:01BB 06 00000000:00000000 03:000012E8 00000000  0  0 0 3 00000000 
    5: 8D0BA8C0:D1A1 96E67D4A:01BB 01 00000000:00000000 00:00000000 00000000 1000  0 1672130 1 00000000 24 4 18 5 -1 
    6: 8D0BA8C0:D148 97E67D4A:01BB 01 00000000:00000000 00:00000000 00000000 1000  0 1679875 1 00000000 24 4 20 5 -1 

청취 소켓이 원격 주소를 00000000있을 것이다 포트 쌍 진수에 있습니다. 참조 : * How can i match each /proc/net/tcp entry to each opened socket?

/proc // fd를 사용하여 상호 참조 할 수 있습니다. 예를 들어, sshd는 입니다.

$ cat /var/run/sshd.pid 
522 

$ sudo ls -l /proc/522/fd 
total 0 
lrwx------ 1 root root 64 2011-09-15 21:32 0 -> /dev/null 
lrwx------ 1 root root 64 2011-09-15 21:32 1 -> /dev/null 
lrwx------ 1 root root 64 2011-09-15 21:32 2 -> /dev/null 
lrwx------ 1 root root 64 2011-09-15 21:32 3 -> socket:[6456] 
lrwx------ 1 root root 64 2011-09-15 21:32 4 -> socket:[6458] 

소켓 6456은 은/proc/순/TCP의 두 번째 행에 나열된 inode에 6458에 해당한다.

그래서 당신은 시저에서 모든 정보를 얻을 수 있습니다,하지만 당신은 -lntp

3

나는이 질문은 오래 알고 NETSTAT 개혁까지 끝낼 수 있습니다,하지만 난 begginners이 물품. 시스템에서 청취 포트를 식별하려면 아래 코드를 사용할 수 있습니다.

from socket import * 

Port = 0 #First port. 
while Port <= 65535: #Port 65535 is last port you can access. 
    try: 
     try: 
      Socket = socket(AF_INET, SOCK_STREAM, 0) #Create a socket. 
     except: 
      print("Error: Can't open socket!\n")  
      break #If can't open socket, exit the loop. 
     Socket.connect(("127.0.0.1", Port)) #Try connect the port. If port is not listening, throws ConnectionRefusedError. 
     Connected = True 
    except ConnectionRefusedError: 
     Connected = False  
    finally: 
     if(Connected and Port != Socket.getsockname()[1]): #If connected, 
      print("{}:{} Open \n".format("127.0.0.1", Port)) #print port. 
     Port = Port + 1 #Increase port. 
     Socket.close() #Close socket.