socket

(图片来自互联网)

说到socket,学过网络基础的人都听过,他是TCP/IP的抽象,他是网络世界的入口,它无处不在。

学会了socket编程,就意味着能够更深层次的控制你的流量,之后再看python的urllib*或php的curl,简直就是小儿科!

一些名词

Address Family

地址类型,协议族,可能是以下

socket.AF_INET ---> IPv4 addresses.
socket.AF_INET6 ---> IPv6 addresses.
socket.AF_UNIX ---> Unix domain sockets (例如 /var/run/mysqld/mysqld.sock is an example).
socket.AF_IPX ---> IPX addresses.

Socktype

sock类型

socket.SOCK_STREAM ---> 流式socket , for TCP
socket.SOCK_DGRAM ---> 数据报式socket , for UDP

其他

参数取值说明
Address FamilyAF_INET2IPv4
AF_INET623IPv6
AF_UNSPEC0协议无关
Protocol Numbers 协议号IPPROTO_IP0IP协议
IPPROTO_IPV44IPv4
IPPROTO_IPV641IPv6
IPPROTO_UDP17UDP
IPPROTO_TCP6TCP
Socktype sock类型SOCK_STREAM1
SOCK_DGRAM2数据报
ai_flagsAI_PASSIVE1被动的,用于bind,通常用于server socket
AI_CANONNAME2用于返回主机的规范名称
  
AI_NUMERICHOST4地址为数字串
## 简单的例子

来自官方文档的例子,很基础。

服务端

# Echo server program
import socket

HOST = '127.0.0.1'                 # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
    data = conn.recv(1024)
    if not data: break
    conn.sendall(data)
conn.close()

客户端

# Echo client program
import socket

HOST = 'localhost'    # The remote host
PORT = 50007              # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)

更复杂的例子

服务端

与之前不同的是,支持IPV6

# Echo server program
import socket
import sys

HOST = None               # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
                              socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
    af, socktype, proto, canonname, sa = res
    try:
        s = socket.socket(af, socktype, proto)
    except socket.error as msg:
        s = None
        continue
    try:
        s.bind(sa)
        s.listen(1)
    except socket.error as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print 'could not open socket'
    sys.exit(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
    data = conn.recv(1024)
    if not data: break
    conn.send(data)
conn.close()

客户端

# Echo client program
import socket
import sys

HOST = 'localhost'    # The remote host
PORT = 50007              # The same port as used by the server
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM):
    af, socktype, proto, canonname, sa = res
    try:
        s = socket.socket(af, socktype, proto)
    except socket.error as msg:
        s = None
        continue
    try:
        s.connect(sa)
    except socket.error as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print 'could not open socket'
    sys.exit(1)
s.sendall('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)

标签: socket, lesson

添加新评论