selfboot / AnnotatedShadowSocks

Annotated shadowsocks(python version)
Other
3 stars 1 forks source link

Socket: addressing, protocol families and socket types #12

Open selfboot opened 7 years ago

selfboot commented 7 years ago

A socket is one endpoint of a communication channel used by programs to pass data back and forth locally or across the Internet. Sockets have two primary properties controlling the way they send data: the address family controls the OSI network layer protocol used and the socket type controls the transport layer protocol.

Python supports three address families:

The socket type is usually either SOCK_DGRAM for user datagram protocol (UDP) or SOCK_STREAM for transmission control protocol (TCP). UDP does not require transmission handshaking or other setup, but offers lower reliability of delivery. UDP messages may be delivered out of order, more than once, or not at all. TCP, by contrast, ensures that each message is delivered exactly once, and in the correct order. Most application protocols that deliver a large amount of data, such as HTTP, are built on top of TCP. UDP is commonly used for protocols where order is less important (since the message fits in a single packet, i.e., DNS), or for multicasting (sending the same data to several hosts).

socket includes functions to interface with the domain name services on the network, to convert the host name of a server into its numerical network address. Use gethostbyname() to convert the name of a server to its numerical address:

>>> print socket.gethostbyname('www.baidu.com')
183.232.231.173
>>> ^D
$ ping www.baidu.com
PING www.a.shifen.com (183.232.231.173): 56 data bytes
64 bytes from 183.232.231.173: icmp_seq=0 ttl=49 time=34.072 ms

When the address of a server is available, use gethostbyaddr() to do a “reverse” lookup for the name.

>>> import socket
>>> socket.gethostbyaddr('8.8.8.8')
('google-public-dns-a.google.com', ['8.8.8.8.in-addr.arpa'], ['8.8.8.8'])

If you get socket.herror: [Errno 1] Unknown host, that's mainly because the ip does not have a valid PTR record, refer to Difficulty using Python's socket.gethostbyaddr() for more details.

IP Address Representations

Network programs written in C use the data type struct sockaddr to represent IP addresses as binary values (instead of the string addresses usually found in Python programs). Convert IPv4 addresses between the Python representation and the C representation with inet_aton() and inet_ntoa().

>>> socket.inet_aton('192.168.1.1')
'\xc0\xa8\x01\x01'
>>> socket.inet_ntoa('\xc0\xa8\x01\x01')
'192.168.1.1'

The four bytes in the packed format can be passed to C libraries, transmitted safely over the network, or saved to a database compactly.

The related functions inet_pton() and inet_ntop() work with both IPv4 and IPv6 addresses, producing the appropriate format based on the address family parameter passed in.

Ref:

https://pymotw.com/2/socket/index.html#module-socket__
https://github.com/xuelangZF/AnnotatedShadowSocks/issues/9