---恢复内容开始---
套接字是计算机网络数据结构,它体现了上节中所描述的“通信端点”的概念。在任何 类型的通信开始之前,网络应用程序必须创建套接字。可以将它们比作电话插孔,没有它将 无法进行通信。
起源
套接字的起源可以追溯到 20 世纪 70 年代,它是加利福尼亚大学的伯克利版本 UNIX(称 为 BSD UNIX)的一部分。因此,有时你可能会听过将套接字称为伯克利套接字或 BSD 套接 字。套接字最初是为同一主机上的应用程序所创建,使得主机上运行的一个程序(又名一个 进程)与另一个运行的程序进行通信。这就是所谓的进程间通信(Inter Process Communication, IPC)。有两种类型的套接字:基于文件的和面向网络的。
基于文件类型的套接字家族
UNIX 套接字是我们所讲的套接字的第一个家族。
并且拥有一个“家族名字”AF_UNIX (又名 AF_LOCAL,在 POSIX1.g 标准中指定),它代表地址家族(address family):UNIX。
unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信
基于网络类型的套接字家族
第二种类型的套接字是基于网络的,它也有自己的家族名字 AF_INET,或者地址家族: 因特网。
另一个地址家族 AF_INET6 用于第 6 版因特网协议(IPv6)寻址。此外,还有其他 的地址家族,这些要么是专业的、过时的、很少使用的,要么是仍未实现的。
在所有的地址 家族之中,目前 AF_INET 是使用得最广泛的。
套接字地址:主机-端口对
如果一个套接字像一个电话插孔——允许通信的一些基础设施,那么主机名和端口号就 像区号和电话号码的组合。
然而,拥有硬件和通信的能力本身并没有任何好处,除非你知道 电话打给谁以及如何拨打电话。一个网络地址由主机名和端口号对组成,而这是网络通信所 需要的。
此外,并未事先说明必须有其他人在另一端接听;否则,你将听到这个熟悉的声音 “对不起,您所拨打的电话是空号,请核对后再拨”。你可能已经在浏览网页的过程中见过一 个网络类比,例如“无法连接服务器,服务器没有响应或者服务器不可达。”
有效的端口号范围为 0~65535(尽管小于 1024 的端口号预留给了系统)。如果你正在使 用 POSIX 兼容系统(如 Linux、Mac OS X 等),那么可以在/etc/services 文件中找到预留端口 号的列表(以及服务器/协议和套接字类型)。众所周知的端口号列表可以在这个网站中查看: http://www.iana.org/assignments/port-numbers。
socket工作原理
生活中的场景就解释了这工作原理。你和朋友通电话,有要先拨打号码,一朋友听到铃声接通电话,你们建立了连接。
然后通话相当于交流信息,然后挂断电话,结束交谈!
面向连接的套接字与无连接的套接字
1.面向连接的套接字
不管你采用的是哪种地址家族,都有两种不同风格的套接字连接。第一种是面向连接的, 这意味着在进行通信之前必须先建立一个连接,例如,使用电话系统给一个朋友打电话。这 种类型的通信也称为虚拟电路或流套接字。
面向连接的通信提供序列化的、可靠的和不重复的数据交付,而没有记录边界。这基本 上意味着每条消息可以拆分成多个片段,并且每一条消息片段都确保能够到达目的地,然后 将它们按顺序组合在一起,最后将完整消息传递给正在等待的应用程序。
实现这种连接类型的主要协议是传输控制协议(更为人熟知的是它的缩写 TCP)。为 了 创建 TCP 套接字,必须使用 SOCK_STREAM 作为套接字类型。TCP 套接字的名字 SOCK_STREAM 基于流套接字的其中一种表示。
因为这些套接字(AF_INET)的网络版本 使用因特网协议(IP)来搜寻网络中的主机,所以整个系统通常结合这两种协议(TCP 和 IP) 来进行(当然,也可以使用 TCP 和本地[非网络的 AF_LOCAL/AF_UNIX]套接字,但是很明 显此时并没有使用 IP)。
2.无连接的套接字
与虚拟电路形成鲜明对比的是数据报类型的套接字,它是一种无连接的套接字。这意味 着,在通信开始之前并不需要建立连接。此时,在数据传输过程中并无法保证它的顺序性、 可靠性或重复性。然而,数据报确实保存了记录边界,这就意味着消息是以整体发送的,而 并非首先分成多个片段,例如,使用面向连接的协议。
实现这种连接类型的主要协议是用户数据报协议(更为人熟知的是其缩写 UDP)。为 了 创建 UDP 套接字,必须使用 SOCK_DGRAM 作为套接字类型。你可能知道,UDP 套接字的 SOCK_DGRAM 名字来自于单词“datagram”(数据报)。
因为这些套接字也使用因特网协议 来寻找网络中的主机,所以这个系统也有一个更加普通的名字,即这两种协议(UDP 和 IP) 的组合名字,或 UDP/IP。
tcp协议与udp协议区别
TCP(Transmission Control Protocol)可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:Web浏览器;电子邮件、文件传输程序。
UDP(User Datagram Protocol)不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文,尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)。
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)
一旦有了一个套接字对象,那么使用套接字对象的方法将可以进行进一步的交互。
套接字对象(内置)方法
名称
描述
服务器套接字方法
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.getpeername()
连接到套接字(TCP)的远程地址
s.getsockopt()
返回给定套接字选项的值
s.setsockopt()
设置给定套接字选项的值
s.shutdown()
关闭连接
s.close()
关闭套接字
s.detach()②
在未关闭文件描述符的情况下关闭套接字,返回文件描述符
s.ioctl()③
控制套接字的模式(仅支持 Windows)
面向阻塞的套接字方法
s.setblocking()
设置套接字的阻塞或非阻塞模式
s.settimeout()④
设置阻塞套接字操作的超时时间
s.gettimeout()④
获取阻塞套接字操作的超时时间
面向文件套接字方法
s.fileno()
套接字的文件描述符
s.makefile()
创建与套接字关联的文件对象
数据属性
s.family①
套接字家族
s.type①
套接字类型
s.proto①
套接字协议
① Python 2.5 中新增。 ② Python 3.2 中新增。 ③ Python 2.6 中新增,仅仅支持 Windows 平台;POSIX 系统可以使用 functl 模块函数。 ④ Python 2.3 中新增。
Socket模块初使用
基于TCP 协议的 socket
tcp 是基于链接的 ,必须先启动server端,再去启动clien 端去链接服务端。
server端
#导入模块
importsocket#实力一个sk接口
sk =socket.socket() #socket()默认TCP协议#绑定地址,(‘ip’,端口)
sk.bind(('127.0.0.1',8899))#监听链接
sk.listen()#接收客户端链接 ,conn建立好的链接,addr客户端地址
conn,addr =sk.accept()#接收消息
ret = conn.recv(1024)print(ret)#向客户端发送消息
conn.send(b'hello')#关闭客户端套接字
conn.close()#关闭服务端套接字
sk.close()
clien端
importsocket
sk= socket.socket() #创建客户端sk
sk.connect(('127.0.0.1',8899)) #去链接服务端(‘ip',端口)
sk.send(b'ha,ha') #向服务端发送消息
ret = sk.recv(1024) #接收消息
print(ret)
sk.close()#关闭
问题:重启服务端时可能会遇到
我们可能会遇到下面的问题:
解决方法:
#加入一条socket配置,重用ip和端口
importsocketfrom socket importSOL_SOCKET,SO_REUSEADDR
sk=socket.socket()
sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加
sk.bind(('127.0.0.1',8898)) #把地址绑定到套接字
sk.listen() #监听链接
conn,addr = sk.accept() #接受客户端链接
ret = conn.recv(1024) #接收客户端信息
print(ret) #打印客户端信息
conn.send(b'hi') #向客户端发送信息
conn.close() #关闭客户端套接字
sk.close() #关闭服务器套接字(可选)
View Code
TCP 时间戳服务器
创建 TCP 服务器
server端
它是一个 TCP 服务器程序,它接受客户端发送的数据 字符串,并将其打上时间戳(格式:[时间戳]数据)并返回给客户端(“server”代表时间戳 TCP 服务器,其他文件以类似的方式命名)。
服务端
from socket import *
from time import ctime #导入了 time.ctime()和 socket 模块的所有属性。
host= '127.0.0.1' #本地回环地址
port = 9000 #端口
bufsiz = 1024 #将缓冲区大小设置为 1KB
addr =(host, port)
tcpsk=socket(AF_INET, SOCK_STREAM)
tcpsk.bind(addr)#绑定地址
tcpsk.listen(5) #listen()方法的参数是在连接被转接或拒绝之前,传入连接请求的最大数。
whileTrue:print('waiting for connection.....')
Conn,Addr=tcpsk.accept()print('...connected from:',Addr)whileTrue:
data= Conn.recv(bufsiz).decode('utf-8')print(data)if notdata:breakdata= '[%s] %s' %(ctime(), data)
Conn.send(data.encode('utf-8') ) #ctime()当前格式化时间
Conn.close()
tcpsk.close()
创建 TCP 客户端
clien端
这个脚本连接到服务器,并以逐行数据的形式提 示用户。服务器则返回加了时间戳的相同数据,这些数据最终会通过客户端代码呈现给 用户。
from socket import *host= '127.0.0.1' #本地回环地址
port = 9000 #端口
bufsiz = 1024 #将缓冲区大小设置为 1KB
addr =(host, port)
tcpck=socket(AF_INET,SOCK_STREAM)
tcpck.connect(addr)whileTrue:
data= input('>').encode('utf-8')if notdata:breaktcpck.send(data)
data= tcpck.recv(bufsiz).decode('utf-8')if notdata:break
print(data)
tcpck.close()
客户端
基于UDP 协议的 socket
创建UDP服务器
UDP 服务器不需要 TCP 服务器那么多的设置,因为它们不是面向连接的。除了等待传 入的连接之外,几乎不需要做其他工作。
UDP 和TCP服务器之间还有另一个显著区别,因为数据包套接字是无连接的,所以就没有为了成功的通信,而使一个客户端连接到一个独立的套接字“转换的操作”,这些服务器仅仅接受消息并有可能回复消息。
---恢复内容结束---
套接字是计算机网络数据结构,它体现了上节中所描述的“通信端点”的概念。在任何 类型的通信开始之前,网络应用程序必须创建套接字。可以将它们比作电话插孔,没有它将 无法进行通信。
起源
套接字的起源可以追溯到 20 世纪 70 年代,它是加利福尼亚大学的伯克利版本 UNIX(称 为 BSD UNIX)的一部分。因此,有时你可能会听过将套接字称为伯克利套接字或 BSD 套接 字。套接字最初是为同一主机上的应用程序所创建,使得主机上运行的一个程序(又名一个 进程)与另一个运行的程序进行通信。这就是所谓的进程间通信(Inter Process Communication, IPC)。有两种类型的套接字:基于文件的和面向网络的。
基于文件类型的套接字家族
UNIX 套接字是我们所讲的套接字的第一个家族。
并且拥有一个“家族名字”AF_UNIX (又名 AF_LOCAL,在 POSIX1.g 标准中指定),它代表地址家族(address family):UNIX。
unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信
基于网络类型的套接字家族
第二种类型的套接字是基于网络的,它也有自己的家族名字 AF_INET,或者地址家族: 因特网。
另一个地址家族 AF_INET6 用于第 6 版因特网协议(IPv6)寻址。此外,还有其他 的地址家族,这些要么是专业的、过时的、很少使用的,要么是仍未实现的。
在所有的地址 家族之中,目前 AF_INET 是使用得最广泛的。
套接字地址:主机-端口对
如果一个套接字像一个电话插孔——允许通信的一些基础设施,那么主机名和端口号就 像区号和电话号码的组合。
然而,拥有硬件和通信的能力本身并没有任何好处,除非你知道 电话打给谁以及如何拨打电话。一个网络地址由主机名和端口号对组成,而这是网络通信所 需要的。
此外,并未事先说明必须有其他人在另一端接听;否则,你将听到这个熟悉的声音 “对不起,您所拨打的电话是空号,请核对后再拨”。你可能已经在浏览网页的过程中见过一 个网络类比,例如“无法连接服务器,服务器没有响应或者服务器不可达。”
有效的端口号范围为 0~65535(尽管小于 1024 的端口号预留给了系统)。如果你正在使 用 POSIX 兼容系统(如 Linux、Mac OS X 等),那么可以在/etc/services 文件中找到预留端口 号的列表(以及服务器/协议和套接字类型)。众所周知的端口号列表可以在这个网站中查看: http://www.iana.org/assignments/port-numbers。
socket工作原理
生活中的场景就解释了这工作原理。你和朋友通电话,有要先拨打号码,一朋友听到铃声接通电话,你们建立了连接。
然后通话相当于交流信息,然后挂断电话,结束交谈!
面向连接的套接字与无连接的套接字
1.面向连接的套接字
不管你采用的是哪种地址家族,都有两种不同风格的套接字连接。第一种是面向连接的, 这意味着在进行通信之前必须先建立一个连接,例如,使用电话系统给一个朋友打电话。这 种类型的通信也称为虚拟电路或流套接字。
面向连接的通信提供序列化的、可靠的和不重复的数据交付,而没有记录边界。这基本 上意味着每条消息可以拆分成多个片段,并且每一条消息片段都确保能够到达目的地,然后 将它们按顺序组合在一起,最后将完整消息传递给正在等待的应用程序。
实现这种连接类型的主要协议是传输控制协议(更为人熟知的是它的缩写 TCP)。为 了 创建 TCP 套接字,必须使用 SOCK_STREAM 作为套接字类型。TCP 套接字的名字 SOCK_STREAM 基于流套接字的其中一种表示。
因为这些套接字(AF_INET)的网络版本 使用因特网协议(IP)来搜寻网络中的主机,所以整个系统通常结合这两种协议(TCP 和 IP) 来进行(当然,也可以使用 TCP 和本地[非网络的 AF_LOCAL/AF_UNIX]套接字,但是很明 显此时并没有使用 IP)。
2.无连接的套接字
与虚拟电路形成鲜明对比的是数据报类型的套接字,它是一种无连接的套接字。这意味 着,在通信开始之前并不需要建立连接。此时,在数据传输过程中并无法保证它的顺序性、 可靠性或重复性。然而,数据报确实保存了记录边界,这就意味着消息是以整体发送的,而 并非首先分成多个片段,例如,使用面向连接的协议。
实现这种连接类型的主要协议是用户数据报协议(更为人熟知的是其缩写 UDP)。为 了 创建 UDP 套接字,必须使用 SOCK_DGRAM 作为套接字类型。你可能知道,UDP 套接字的 SOCK_DGRAM 名字来自于单词“datagram”(数据报)。
因为这些套接字也使用因特网协议 来寻找网络中的主机,所以这个系统也有一个更加普通的名字,即这两种协议(UDP 和 IP) 的组合名字,或 UDP/IP。
tcp协议与udp协议区别
TCP(Transmission Control Protocol)可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:Web浏览器;电子邮件、文件传输程序。
UDP(User Datagram Protocol)不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文,尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)。
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)
一旦有了一个套接字对象,那么使用套接字对象的方法将可以进行进一步的交互。
套接字对象(内置)方法
名称
描述
服务器套接字方法
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.getpeername()
连接到套接字(TCP)的远程地址
s.getsockopt()
返回给定套接字选项的值
s.setsockopt()
设置给定套接字选项的值
s.shutdown()
关闭连接
s.close()
关闭套接字
s.detach()②
在未关闭文件描述符的情况下关闭套接字,返回文件描述符
s.ioctl()③
控制套接字的模式(仅支持 Windows)
面向阻塞的套接字方法
s.setblocking()
设置套接字的阻塞或非阻塞模式
s.settimeout()④
设置阻塞套接字操作的超时时间
s.gettimeout()④
获取阻塞套接字操作的超时时间
面向文件套接字方法
s.fileno()
套接字的文件描述符
s.makefile()
创建与套接字关联的文件对象
数据属性
s.family①
套接字家族
s.type①
套接字类型
s.proto①
套接字协议
① Python 2.5 中新增。 ② Python 3.2 中新增。 ③ Python 2.6 中新增,仅仅支持 Windows 平台;POSIX 系统可以使用 functl 模块函数。 ④ Python 2.3 中新增。
Socket模块初使用
基于TCP 协议的 socket
tcp 是基于链接的 ,必须先启动server端,再去启动clien 端去链接服务端。
server端
#导入模块
importsocket#实力一个sk接口
sk =socket.socket() #socket()默认TCP协议#绑定地址,(‘ip’,端口)
sk.bind(('127.0.0.1',8899))#监听链接
sk.listen()#接收客户端链接 ,conn建立好的链接,addr客户端地址
conn,addr =sk.accept()#接收消息
ret = conn.recv(1024)print(ret)#向客户端发送消息
conn.send(b'hello')#关闭客户端套接字
conn.close()#关闭服务端套接字
sk.close()
clien端
importsocket
sk= socket.socket() #创建客户端sk
sk.connect(('127.0.0.1',8899)) #去链接服务端(‘ip',端口)
sk.send(b'ha,ha') #向服务端发送消息
ret = sk.recv(1024) #接收消息
print(ret)
sk.close()#关闭
问题:重启服务端时可能会遇到
我们可能会遇到下面的问题:
解决方法:
#加入一条socket配置,重用ip和端口
importsocketfrom socket importSOL_SOCKET,SO_REUSEADDR
sk=socket.socket()
sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加
sk.bind(('127.0.0.1',8898)) #把地址绑定到套接字
sk.listen() #监听链接
conn,addr = sk.accept() #接受客户端链接
ret = conn.recv(1024) #接收客户端信息
print(ret) #打印客户端信息
conn.send(b'hi') #向客户端发送信息
conn.close() #关闭客户端套接字
sk.close() #关闭服务器套接字(可选)
View Code
TCP 时间戳服务器
创建 TCP 服务器
server端
它是一个 TCP 服务器程序,它接受客户端发送的数据 字符串,并将其打上时间戳(格式:[时间戳]数据)并返回给客户端(“server”代表时间戳 TCP 服务器,其他文件以类似的方式命名)。
服务端
from socket import *
from time import ctime #导入了 time.ctime()和 socket 模块的所有属性。
host= '127.0.0.1' #本地回环地址
port = 9000 #端口
bufsiz = 1024 #将缓冲区大小设置为 1KB
addr =(host, port)
tcpsk=socket(AF_INET, SOCK_STREAM)
tcpsk.bind(addr)#绑定地址
tcpsk.listen(5) #listen()方法的参数是在连接被转接或拒绝之前,传入连接请求的最大数。
whileTrue:print('waiting for connection.....')
Conn,Addr=tcpsk.accept()print('...connected from:',Addr)whileTrue:
data= Conn.recv(bufsiz).decode('utf-8')print(data)if notdata:breakdata= '[%s] %s' %(ctime(), data)
Conn.send(data.encode('utf-8') ) #ctime()当前格式化时间
Conn.close()
tcpsk.close()
创建 TCP 客户端
clien端
这个脚本连接到服务器,并以逐行数据的形式提 示用户。服务器则返回加了时间戳的相同数据,这些数据最终会通过客户端代码呈现给 用户。
from socket import *host= '127.0.0.1' #本地回环地址
port = 9000 #端口
bufsiz = 1024 #将缓冲区大小设置为 1KB
addr =(host, port)
tcpck=socket(AF_INET,SOCK_STREAM)
tcpck.connect(addr)whileTrue:
data= input('>').encode('utf-8')if notdata:breaktcpck.send(data)
data= tcpck.recv(bufsiz).decode('utf-8')if notdata:break
print(data)
tcpck.close()
客户端
基于UDP 协议的 socket
创建UDP服务器
UDP 服务器不需要 TCP 服务器那么多的设置,因为它们不是面向连接的。除了等待传 入的连接之外,几乎不需要做其他工作。
importsocketimport time #导入时间模块
HOST = '127.0.0.1'PORT= 9000BUFSIZ= 1024ADDR=(HOST,PORT)配置变量
udpsk= socket.socket(type =socket.SOCK_DGRAM)
udpsk.bind(ADDR)#bind的调用与TCP相同
#不同之处在于这里没用“监听传入的连接”,因为UDP是无连接的
whileTrue:print('message..')
data,addr=udpsk.recvfrom(BUFSIZ)
msg= data.decode('utf-8')
T= '[%s] %s' %(time.ctime(),msg)
udpsk.sendto(T.encode('utf-8'),addr)print(':',addr)
udpsk.close()
server
UDP时间戳客户端,它提示用户输入发送给服务器的消息,并接收消息,并接收服务器加了时间戳前缀的消息,然后显示给用户。
importsocket
HOST= '127.0.0.1'PORT= 9000BUFSIZ= 1024ADDR= (HOST,PORT)#配置变量
udpck = socket.socket(type=socket.SOCK_DGRAM)#udp协议的socket()
whileTrue:
data= input('>').encode('utf-8')if notdata:breakudpck.sendto(data, ADDR)
mag,ADDR=udpck.recvfrom(BUFSIZ)
l= mag.decode('utf-8')if notdata:break
print(l,ADDR)
udpck.close()
client