0%

python的socket编程笔记

参考:https://gist.github.com/kevinkindom/108ffd675cb9253f8f71

python提供了两个socket模块:

  • Socket:提供标准的BSD Socket API
  • SocketServer:提供服务器中心,可简化网络服务器开发

这里主要学习Socket模块。

创建Socket

格式:socket(family, type[,protocal])

使用给定套接族,套接字类型,协议编号(默认为0)创建套接字

socket 类型 描述
socket.AF_UNIX 用于同一台机器上的进程通信(既本机通信)
socket.AF_INET 用于服务器与服务器之间的网络通信
socket.AF_INET6 基于IPV6方式的服务器与服务器之间的网络通信
socket.SOCK_STREAM 基于TCP的流式socket通信
socket.SOCK_DGRAM 基于UDP的数据报式socket通信

例:

1
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Socket函数

TCP发送数据时,已建立好TCP链接,所以不需要指定地址,而UDP是面向无连接的,每次发送都需要指定发送给谁。服务器与客户端发送的数据是字符串。

服务器端 Socket 函数

Socket 函数 描述
s.bind(address) 将套接字绑定到地址,在AF_INET下,以tuple(host, port)的方式传入,如s.bind((host, port))
s.listen(backlog) 开始监听TCP传入连接,backlog指定在拒绝链接前,操作系统可以挂起的最大连接数,该值最少为1,大部分应用程序设为5
s.accept() 接受TCP链接并返回(conn, address),其中conn是新的套接字对象,可以用来接收和发送数据,address是链接客户端的地址。

客户端 Socket 函数

Socket 函数 描述
s.connect(address) 链接到address处的套接字,一般address的格式为tuple(host, port),如果链接出错,则返回socket.error错误

公共 Socket 函数

Socket 函数 描述
s.recv(bufsize[, flag]) 接受TCP套接字的数据,数据以字符串形式返回,buffsize指定要接受的最大数据量,flag提供有关消息的其他信息,通常可以忽略
s.send(string[, flag]) 发送TCP数据,将字符串中的数据发送到链接的套接字,返回值是要发送的字节数量,该数量可能小于string的字节大小
s.settimeout(timeout) 设置套接字操作的超时时间,timeout是一个浮点数,单位是秒,值为None则表示永远不会超时。一般超时期应在刚创建套接字时设置,因为他们可能用于连接的操作,如s.connect()
s.recvfrom(bufsize[, flag]) 接受UDP套接字的数据u,与recv()类似,但返回值是tuple(data, address)。其中data是包含接受数据的字符串,address是发送数据的套接字地址
s.sendto(string[, flag], address) 发送UDP数据,将数据发送到套接字,address形式为tuple(ipaddr, port),指定远程地址发送,返回值是发送的字节数
s.close() 关闭套接字

步骤

TCP 服务器

1、创建套接字,绑定套接字到本地IP与端口

1
2
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind()

2、开始监听链接

1
s.listen()

3、进入循环,不断接受客户端的链接请求

1
2
While True:
s.accept()

4、接收客户端传来的数据,并且发送给对方发送数据

1
2
s.recv()
s.sendall()

5、传输完毕后,关闭套接字

1
s.close()

TCP 客户端

1、创建套接字并链接至远端地址

1
2
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect()

2、链接后发送数据和接收数据

1
2
s.sendall()
s.recv()

3、传输完毕后,关闭套接字

实例

Socket 编程实践之服务器端代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import socket

HOST = '192.168.1.100'
PORT = 8001

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(5)

print 'Server start at: %s:%s' %(HOST, PORT)
print 'wait for connection...'

while True:
conn, addr = s.accept()
print 'Connected by ', addr

while True:
data = conn.recv(1024)
print data

conn.send("server received you message.")

# conn.close()

Socket 编程实践之客户端代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import socket
HOST = '192.168.1.100'
PORT = 8001

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))

while True:
cmd = raw_input("Please input msg:")
s.send(cmd)
data = s.recv(1024)
print data

#s.close()

编程时一定要注意编码方式啊……比如下面:

1
print(u'q' == b'q')

结果为False。

本来想当输入“q”时就断开TCP连接,结果因为编码不同,一直没跳出循环,导致了报错。

u/U:表示unicode字符串

r/R:非转义的原始字符串

在python中交换两个列表:

如大小相等的2个列表a, b,交换这两个列表的内容:

1
a, b = b, a

也等同于:

1
2
3
mid = a
a = b
b = mid