python之socket

cs模式中,服务器需要完成以下任务

  1. 创建socket()
  2. 绑定bind()
  3. 监听listen()
  4. 接受accept()

而客户端要完成

  1. 创建socket()
  2. 连接connet()

当应用进程发出socket系统调用时,操作系统会在自己的套接字描述符表中添加一个套接字描述符,这个套接字描述符指向一个套接字

在套接字的数据结构中有许多参数需要填写

创建socket

刚刚创建一个新的套接字的时候,要指定协议族服务类型

下面用python创建一个socket

import socket
# 这里使用的是AF_INET(PF_INET),Pv4网络协议的套接字类型
# (SOCK_STREAM,表示使用流式服务,也就是TCP服务)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

绑定

当套接字被创建后,它的端口号和ip地址都是空的,因此应用进程要调用bind(绑定)来指明套接字的本地地址(含本地端口号和本地IP地址).

# 注意bind()参数是个二元的tuple,(IP地址, 端口)
# python中可以用socket.gethostname()得到本地地址
# 当地址为127.0.0.1或localhost的时候是本机通信,客户端和服务端在一台机器上
# 为空则默认为都可以连接
s.bind(('',5000))

监听

接下来就是通过监听,把套接字设置为被动方式,一边接受客户的服务请求(如果是UDP服务器提供无连接的服务,所以不适用listen)

# 1 表示  the maximum number of queued connections 
s.listen(1)

接收

# conn 是一个socket连接,addr 是地址
conn, addr = s.accept()

example

接下来上官网的例子

# Echo server program
import socket

HOST = ''                 # 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 = 'daring.cwi.nl'    # 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)