简单socket编程1
(图片来自互联网)
说到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 Family | AF_INET | 2 | IPv4 |
AF_INET6 | 23 | IPv6 | |
AF_UNSPEC | 0 | 协议无关 | |
Protocol Numbers 协议号 | IPPROTO_IP | 0 | IP协议 |
IPPROTO_IPV4 | 4 | IPv4 | |
IPPROTO_IPV6 | 41 | IPv6 | |
IPPROTO_UDP | 17 | UDP | |
IPPROTO_TCP | 6 | TCP | |
Socktype sock类型 | SOCK_STREAM | 1 | 流 |
SOCK_DGRAM | 2 | 数据报 | |
ai_flags | AI_PASSIVE | 1 | 被动的,用于bind,通常用于server socket |
AI_CANONNAME | 2 | 用于返回主机的规范名称 | |
AI_NUMERICHOST | 4 | 地址为数字串 |
来自官方文档的例子,很基础。
服务端
# 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)