自学Python 59 Socket套接字编程 (二)使用socket建立 TCP和UDP“客户端/服务器”连接

Python 使用 socket建立 TCP和UDP“客户端/服务器”连接


文章目录

  • Python 使用 socket建立 TCP和UDP“客户端/服务器”连接
  • 一、使用 socket建立 TCP“客户端/服务器”连接
  • 二、使用 socket建立 UDP“客户端/服务器”连接


  本文在Socket套接字编程 (一)的基础上,继续介绍Socket编程,利用Socket建立 TCP和UDP“客户端/服务器”连接。


一、使用 socket建立 TCP“客户端/服务器”连接

  在 Python程序中创建TCP服务器时,下面是一段创建通用TCP服务器的一般演示代码。这仅仅只是设计服务器的一种方式。一旦熟悉了服务器设计,大家可以按照自己的需求修改下面的代码来操作服务器。

ss = socket()   #创建服务器套接字
ss.bind()   #套接字与地址绑定
ss.listen() #监听连接
inf_loop:   #服务器无限循环
    cs = ss.accept()    #接受客户端连接
comm_loop:  #通信循环
    cs.recv()/cs.send() #对话(接收/发送)
cs.close()  #关闭客户端套接字
ss.close()  #关闭服务器套接字#(可选)

  在 Python程序中,所有套接字都是通过socket.socket()函数创建的。因为服务器需要占用一个端口并等待客户端的请求,所以它们必须绑定到一个本地地址。因为TCP是一种面向连接的通信系统,所以在TCP 服务器开始操作之前,必须安装一些基础设施。特别地,TCP服务器必须监听(传入)的连接。一旦这个安装过程完成后,服务器就可以开始它的无限循环。在调用accept()函数之后,就开启了一个简单的(单线程)服务器,它会等待客户端的连接。在默认情况下,accept()函数是阻塞的,这说明执行操作会被暂停,直到一个连接到达为止。一旦服务器接受了一个连接,就会利用 accept()方法返回一个独立的客户端套接字,用来与即将到来的消息进行交换。
  例如在下面的实例代码中,演示了socket建立TCP“客户端/服务器连接的过程,这是一个可靠的、相互通信的“客户端/服务器”。

  (1)实例文件jiandanfuwu.py的功能是以TCP连接方式建立一个服务器端程序,能够接收信息并发送信息到客户端。文件jiandanfuwu.py的具体实现代码如下所示。

import socket       #导入Socket模块
HOST = ''       #主机地址为0.0.0.0,表示绑定本机所有网络接口ip地址
PORT= 10000     #定义端口号的初始值
#创建socket对象s,参数分别表示地址和协议类型
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#参数指定使用IP和TCP协议
s.bind((HOST,PORT))     #将套接字与地址绑定
s.listen(1)        #监听连接,参数1表示最多接受多少个等待连接的客户端
conn, addr = s.accept()     #接受客户端连接,建立连接后会返回一个元组,两个元素
toSend = "你好,客户端,这里是服务端!"  # 设置发送数据
print('这里是服务器端',addr)     #打印显示客户端地址
while True:     #连接成功后
    data = conn.recv(1024)  #实行对话操作(接收/发送)
    print("客户端的信息:",data.decode('utf-8'))  #打印显示获取的信息
    #data.decode()将目标二进制数据bytes解码为字符串str类型
    if not data:    #如果没有数据
        break       #终止循环
    conn.sendall(toSend.encode('utf-8'))#发送数据信息
    #toSend.encode()将字符串str编码为二进制数据bytes类型
conn.close ()       #关闭连接

  在上述实例代码中,建立TCP连培之后使用 while语句多次与客户端进行数据交换,直到收到数据为空时会终止服冬器的运行。因为这只是一个服务器端程序,所以运行之后程序不会立即返回交互信息,还等待和客户端建立连接,等和客户端建立连接后才能看到具体的交互效果。

  (2)实例文件jiandankehu.py的功能是建立客户端程,在此需要创建一个 socket 实例,然后调用这个socket实例的connect()函数来连接服务器端。函数connect()的语法格式如下所示。

connect(address)

  参数“address”通常也是一个元组(由一个主机名/IP地址,端口构成),如果要连接本地计算机的话,主机名可直接使用“localhost”,函数connect()能够将socket 连接到远程地址为“address”的计算机。实例文件jiandankehu.py的具体实现代码如下所示。

import socket       #导入socket模块
HOST = 'localhost'       #定义变量HOST的初始值
PORT= 10000     #定义端口号,必须和服务端一致
#创建socket对象s,参数分别表示地址和协议类型
dataSocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
dataSocket.connect((HOST,PORT))      #建立和服务器端的连接
data = "服务端你好,我是客户端! "   #设置发送数据
while data:
    dataSocket.sendall(data.encode('utf-8'))   #发送数据”你好..."
    data = dataSocket.recv(512)      #实行对话操作(接收/发送)
    print("获取服务端的信息:\n",data.decode('utf-8'))   #打印显示接收到的服务器信息
    data = input('请输入信息:\n ')       #信息输入
dataSocket.close()           #关闭连接

  上述代码使用socket 以 TCP连接方式建立了一个简单的客户端程序,基本功能是从键盘录入的信息发送给服务器,并从服务器接收信息。因为服务器端是建立在本地“localhost"的10000端口上,所以上述代码作为其客户端程序,连接的就是本地“localhost”的10000端口。
  当连接成功之后,向服务器端发送了一个默认的信息“服务端你好,我是客户端!”之后,便要从键盘录入信息向服务器端发送,直到录入空信息(敲回车)时退出 while循环,关闭socket 连接。
  先运行jiandanfuwu.py服务器端程序,然后运行jiandankehu.py客户端程序,除了发送一个默认的信息外,从键盘中录入的信息都会发送给服务器,服务器收到后显示并再次转发默认信息“你好,客户端,这里是服务端!”客户端进行显示。执行效果如图所示:
自学Python 59 Socket套接字编程 (二)使用socket建立 TCP和UDP“客户端/服务器”连接_第1张图片
自学Python 59 Socket套接字编程 (二)使用socket建立 TCP和UDP“客户端/服务器”连接_第2张图片

二、使用 socket建立 UDP“客户端/服务器”连接

  在 Python程序中,当便用socket应用传输层的UDP协议建立服务器与客户端程序时,整个实现过程要比使用TCP协议简单一点。基于UDP协议的服务器与客户端在进行数据传送时,不是先建立连接,而是直接进行数据传输。在socket对象中,使用方法recvfrom()接
收数据,具体语法格式如下所示。

recvfrom(Duisize[,flags])		#bufsize用于指定缓冲区大小

  方法recvfrom()主要用来从socket 接收数据,可以连接UDP协议。在socket对象中,使用方法 sendto()发送数据,具体语法格式如下所示。

sendto (bytes, address)

  参数“bytes”表示要发送的数据,参数“address”表示发送信息的目标地址,由目标IP地址和端口构成的元组。主要用来通过 UDP协议将数据发送到指定的服务器端。
  在 Python程序中,UDP 服务器应该不需要 TCP服务器那么多的设置,因为它们不是面向连接的。UDP 服务器除了等待传入的连接之外,几乎不需要做其他工作。例如下面是一段通用的 UDP服务器端代码。

import socket
ss = socket()       #创建服务器套接字
ss.bind()      #绑定服务器套接字
infloop:        #服务器无限循环
    cs = ss.recvfrom()/ss.sendto () #实现对话操作(接收/发送)
ss.close()#关闭服务器套接字

  从上述演示代码中可以看到,除了普通的创建套接字并将其绑定到本地地址(主机名/端口号对)外,并没有额外的工作。无限循环包含接收客户端消息、打上时间戳并返回消息,然后回到等待另一条消息的状态。再一次close()调用是可选的,并且由于无限循环的缘故,它并不会被调用,但它提醒我们,它应该是优雅或智能退出方案的一部分。
  注意:UDP和 TCP服务器之间的另一个显著差异是,因为数据报套接字是无连接的,所以就没有为了成功通信而使一个客户端连接到一个独立的套接字“转换的操作。这些服务器仅仅接收消息并有可能回复数据。

  例如在下面的实例代码中,演示了socket建立UDP“客户端/服务器”连接的过程,UDP是一个不可靠的、相互通信的“客户端/服务器”。
  实例文件UDPserve.py的功能是使用UDP 连接方式建立一个服务器端程序,将接收到的信息直接发回到客户端。文件UDPserve.py的具体实现代码如下所示。

import socket       #导入 socket模块
HOST = ''     #定义变量HOST的初始值
PORT= 10000     #定义变量 PORT的初始值
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((HOST, PORT))        #将套接字与地址绑定
data = True     #设置变量data的初始值
while data:     #如果有数据
    data,address = s.recvfrom(1024) #实现对话操作(接收/发送)
    if data==b'zaijian':        #当接收的数据是zaiian时
        break     #停止循环
    print('UDP服务端接收到的信息是:',data.decode('utf-8'))       #显示接收到的信息
    s.sendto(data, address)     #发送信息
s.close()       #关闭连接

  在上述实现代码中,建立UDP连接之后使用while语句多次与客户进行数据交换,设置上述服务器程序建立在本机的10000端口,当收到“"zajian”"信息时退出while循环,然后关闭服务器。
  实例文件UDPclient.py的具体实现代码如下所示。

import socket       #导入socket模块
HOST = 'localhost'       #定义变量HOST的初始值
PORT = 10000        #定义变量PORT的初始值
#创建socket对象s,参数分别表示地址和协议类型
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
data="你好,这里是UDP客户端!"     #定义变量data的初始值
while data :        #如果有data数据
    s.sendto(data.encode('utf-8'), (HOST, PORT))    #发送数据信息
    if data=='zaijian':        #如果data的值是zaijian
        break       #停止循环
    data,addr = s.recvfrom(512)     #读取数据信息
    print("从服务器接收信息: \n", data.decode('utf-8')) #显示从服务器端接收的信息
    data = input('客户端输入信息: \n')  #信息输入
s.close ()#关闭连接

  上述代码使用socket以UDP连接方式建立了一个简单的客户端程序,当在客户端创建socket后,会直接向服务器端(本机的10000端口)发送数据,而没有进行连接。当用户键入“zaijian”时退出while循环,关闭本程序。执行效果如图所示。
自学Python 59 Socket套接字编程 (二)使用socket建立 TCP和UDP“客户端/服务器”连接_第3张图片
自学Python 59 Socket套接字编程 (二)使用socket建立 TCP和UDP“客户端/服务器”连接_第4张图片

你可能感兴趣的:(Python学习,python)