Hi!请登陆

简单socket编程1

2020-10-31 55 10/31

简单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)

相关推荐