Python进行Socket程序编写使用的主要模块就是 socket 模块,在这个模块中可以找到 socket()函数,该函数用于创建套接字对象。套接字也有自己的方法集,这些方法可以实现基于套接字的网络通信。

1、socket()模块函数

要创建套接字,必须使用 socket.socket()函数,它一般的语法如下。



socket(socket_family, socket_type, protocol=0)



其中,socket_family 是 AF_UNIX 或 AF_INET(如前所述),socket_type 是SOCK_STREAM或 SOCK_DGRAM(也如前所述)。protocol 通常省略,默认为 0。

所以,为了创建 TCP/IP 套接字,可以用下面的方式调用 socket.socket()。

tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

同样,为了创建 UDP/IP 套接字,需要执行以下语句。

udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

因为有很多 socket 模块属性,所以此时使用“from module import *”这种导入方式可以接受,不过这只是其中的一个例外。如果使用“from socket import *”,那么我们就把 socket属性引入到了命名空间中。虽然这看起来有些麻烦,但是通过这种方式将能够大大缩短代码,正如下面所示。

tcpSock = socket(AF_INET, SOCK_STREAM)

一旦有了一个套接字对象,那么使用套接字对象的方法将可以进行进一步的交互。

2、套接字对象(内置)方法

常见的套接字对象方法和属性

名称

描述

服务器套接字方法

s.bind()

将地址(主机名、端口号对)绑定到套接字上

s.listen()

设置并启动TCP监听器

s.accept()

被动接受TCP客户端连接,一直等待指导连接到达(阻塞)

客户端套接字方法

s.connect()

主动发起TCP服务器连接

s.connect_ex()

connect()的扩展版本,此时会以错误码的形式返回问题,而不是抛出一个异常

普通的套接字方法

s.recv()

接收 TCP 消息

s.recv_into()

接收 TCP 消息到指定的缓冲区

s.send()

发送 TCP 消息

s.sendall() 

完整地发送 TCP 消息

s.recvfrom() 

接收 UDP 消息

s.recvfrom_into()

接收 UDP 消息到指定的缓冲区

s.sendto()

发送 UDP 消息

s.shutdown() 

关闭连接

s.close() 

关闭套接字

 3、几个实例。

目前很多教材都是用的Python2.7版本,TCP和UDP部分都有点小问题。

自己分别用TCP和UDP写了时间戳的程序,用的是Python3.6版本。

TCP-Server:



1 # -*- coding: utf-8 -*-
 2 from socket import *
 3 from time import ctime
 4 
 5 HOST = ''
 6 PORT = 21567
 7 BUFSIZ = 1024
 8 ADDR = (HOST, PORT)
 9 
10 tcpSerSock = socket(AF_INET, SOCK_STREAM)#创建服务器套接字
11 tcpSerSock.bind(ADDR)#套接字与地址绑定
12 tcpSerSock.listen(5)#监听连接
13 
14 while True:
15     print('waiting for connection...')
16     tcpCliSock, addr = tcpSerSock.accept()#接受客户端连接
17     print('...connected from:', addr)
18 
19     while True:
20         data = tcpCliSock.recv(BUFSIZ)#接收
21         if not data:
22             break
23         tcpCliSock.send(('[%s] %s' % (ctime(), data.decode())).encode())
24         #发送
25     tcpCliSock.close()
26 tcpSerSock.close()



 

TCP-Client:



1 # -*- coding: utf-8 
 2 from socket import *
 3 
 4 HOST = '127.0.0.1'
 5 PORT = 21567
 6 BUFSIZ = 1024
 7 ADDR = (HOST, PORT)
 8 
 9 tcpCliSock = socket(AF_INET, SOCK_STREAM)
10 tcpCliSock.connect(ADDR)
11 
12 while True:
13     data = input('> ')
14     if not data:
15         break
16     tcpCliSock.send(data.encode())#用encode转换成bytes
17     data = tcpCliSock.recv(BUFSIZ)
18     if not data:
19         break
20     print(data.decode('utf-8'))#用decode转换成str
21 
22 tcpCliSock.close()



 

UDP-Server:



1 # -*- coding: utf-8 -*-
 2 from socket import *
 3 from time import ctime
 4 
 5 HOST = ''
 6 PORT = 21567
 7 BUFSIZ = 1024
 8 ADDR = (HOST, PORT)
 9 
10 udpSerSock = socket(AF_INET, SOCK_DGRAM)
11 udpSerSock.bind(ADDR)
12 
13 while True:
14     print('waiting for message...')
15     data, addr = udpSerSock.recvfrom(BUFSIZ)
16     udpSerSock.sendto(('[%s] %s' % (ctime(), data.decode())).encode(), addr)
17     print('...received from and returned to:', addr)
18 
19 udpSerSock.close()



 

UDP-Client:



1 # -*- coding: utf-8 -*-
 2 from socket import *
 3 
 4 HOST = 'localhost'
 5 PORT = 21567
 6 BUFSIZ = 1024
 7 ADDR = (HOST, PORT)
 8 
 9 udpCliSock = socket(AF_INET, SOCK_DGRAM)
10 
11 while True:
12     data = input('> ')
13     if not data:
14         break
15     udpCliSock.sendto(data.encode(), ADDR)
16     data, ADDR = udpCliSock.recvfrom(BUFSIZ)
17     if not data:
18         break
19     print(data.decode())
20 
21 udpCliSock.close()