2012-03-14 2 views
2

킥 들어 나는 파이썬에서 다음 에코 서버를 썼다. http://ilab.cs.byu.edu/python/socket/echoserver.html은 (내가 여기에서 코드를 복사 생각합니다.) 바인드 호출은 어떻게됩니까? (python + socket + strace)

#!/usr/bin/env python 

import socket 

host = '' 
port = 50000 
backlog = 5 
size = 1024 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.bind((host, port)) 

가 그럼 난 ipython의 strace -o/tmp를/somefile -v를 실행 그리고 선으로 코드 라인의 조각을 삽입하기 시작했다.

출력의 대부분은 의미가 있지만 다음을 이해할 수 없습니다.

bind(4, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0 
getsockname(4, {sa_family=AF_NETLINK, pid=3084, groups=00000000}, [12]) = 0 
sendto(4, "\24\0\0\0\26\0\1\3\300EPO\0\0\0\0\0\0\0\0", 20, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 20 
recvmsg(4, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"0\0\0\0\24\0\2\0\300EPO\f\f\0\0\2\10\200\376\1\0\0\0\10\0\1\0\177\0\0\1"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 108 
recvmsg(4, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"@\0\0\0\24\0\2\0\300EPO\f\f\0\0\n\200\200\376\1\0\0\0\24\0\1\0\0\0\0\0"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 128 
recvmsg(4, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"\24\0\0\0\3\0\2\0\300EPO\f\f\0\0\0\0\0\0\1\0\0\0\24\0\1\0\0\0\0\0"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 20 
close(4)   

위의 strace 출력 다음에 다음 출력이옵니다. 위의 출력은 python2.6에서만 발생합니다.

listen(3, 5)                            = 0 
accept(3, {sa_family=AF_INET, sin_port=htons(45636), sin_addr=inet_addr("127.0.0.1")}, [16]) = 4 
recvfrom(4, "Hey", 1024, 0, NULL, NULL) = 3 
sendto(4, "Heyback", 7, 0, NULL, 0)     = 7 
close(4)                                = 0 
accept(3, 0x7fffdac55fe0, [16])         = ? ERESTARTSYS (To be restarted) 

이 서버는 잘 실행하지만 파일 기술자 4에 무슨 일이 일어나고 있는지 알고 좋아했던, 학술 운동의 더? 왜 python2.6에서만 발생합니까?

내가 그 라인을 기대

답변

3

socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE) = 4 

man 7 netlink 우리에게 보내 무슨의 형식을 알려줍니다 같은 것을 선행되어야하고, 그래서 우리는

struct nlmsghdr _ = { 
    .nlmsglen = 20, 
    .nlmsg_type = RTM_GETADDR, 
    .nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH; 
    .nlmsg_seq = 1330660800, 
    .nlmsg_pid = 0, 
}; 
의 연결로 전송 된 메시지를 디코딩 할 수

및 일부 4 바이트는 0입니다.

무엇이 RTM_GETADDR입니까? man 7 rtnetlink은 각 인터페이스에 대한 IP 주소 정보를 요청합니다. 우리는 응답 본문 struct ifaddrmsg을 디코딩 할 수 있지만, 각 앞의 netlink 헤더는 strace가 데이터 출력을 짧게 만듭니다.

어쨌든 여기에서 그만 두어 을 작성하는 데 필요한 정보를 검색하면 bind으로 전화 할 수 있습니다. 결국 빈 노드 이름을 전달 했으므로 작동하지 않아도됩니다. 이를 확인하고 '''0.0.0.0' ("모든 인터페이스의 모든 주소에 바인딩")으로 변경하면 더 이상이 작은 교환을 볼 수 없습니다.