后台开发核心技术(08):套接字编程

本文介绍了后台开发中的套接字编程,包括UDP和TCP两种实现方式。通过一个简单的回声服务器示例,展示了客户端如何创建套接字发送数据,以及服务器如何接收、处理并返回数据。在UDP中,客户端与服务器通过指定地址和端口通信;而在TCP中,先进行三次握手建立连接,然后无须指定地址即可通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过上篇文章已经看到很多应用层的应用程序,典型的网络应用是由一对程序(客户程序和服务器程序)组成的,它们位于两个不同的端系统中,当运行这两个程序时,创建了一个客户进程和服务器进程,同时它们通过从套接字读出和写入数据在彼此之间进行通信,开发者创建一个网络应用时,其主要任务就是编写客户程序和服务器程序的代码。

我们将使用下列简单的客户-服务器应用程序来演示对于UDPTCP的套接字编程:
1)客户从键盘读取一行字符,并将该字符向服务器发送。
2)服务器接收该数据并将这些数据转化为大写。
3)服务器将修改过的数据发送给客户端。
4)客户端接收修改后的数据并在其监视器上显示出来。

其实这就是一个简单的回声服务器,我们用来测试一下TCP和UDP实现套接字编程的进程间通信。

UDP实现

下图显示了客户和服务器主要的套接字相关的活动:
在这里插入图片描述
假设服务器已经在运行,我们先看一下客户端的代码设计:

// UDPClient.py
from socket import *
serverName = 'hostname'
serverPort = 12000
clientSocket = socket(AF_INET,SOCK_DGRAM)
message = raw_input('Input lowercase sentence:')
clientSocket.sendto(message.encode(),(serverName,serverPort))
modifiedMessage,serverAddress = clientSocket.recvfrom(2048)
print(modifiedMessage.decode())
clientSocket.close()

解释:看一下各行代码

from socket import *

该socket模块形成在python中所有网络通信的基础。

serverName = 'hostname'
serverPort = 12000

这里提供了服务器的名称和端口号,服务器名称可以提供主机名(例如:cis.poly.edu)也可以提供IP地址,如果提供了主机名,那么将自动执行DNS从而得到IP地址。

clientSocket = socket(AF_INET,SOCK_DGRAM)

创建了套接字,用于交互信息的套接字,这里有两个参数,第一个是指地址簇,比如这里的AF_INET指示了底层网络的IPv4,第二个是代表了socket类型,这里的SOCK_DGRAM是指用的UDP套接字,这个服务程序就建立在了UDP的传输层上面。

message = raw_input('Input lowercase sentence:')

raw_input()是python中的内置功能,当执行这条指令时,根据Input lowercase sentence:的提示输入一行字符,然后被存放到message中,发送给服务器。

clientSocket.sendto(message.encode(),(serverName,serverPort))

向服务器发送报文,括号里指定了目的地和端口。

modifiedMessage,serverAddress = clientSocket.recvfrom(2048)

发送给服务器之后调用socket的recvfrom阻塞等待服务器发送来的消息,将修改后的消息放到modifiedMessage中,将源地址放到serverAddress中,包含了服务器的IP地址和端口号。

print(modifiedMessage.decode())

打印出来收到的修改后的消息。

clientSocket.close()

关闭套接字。
现在看一下服务器的实现:

from socket import *
serverPort = 12000
serverSocket = socket(AF_INET,SOCK_DGRAM)
serverSocket.bind(('',serverPort))
print("The server is ready to receive")
while True:
    message,clientAddress = serverSocket.recvfrom(2048)
    modifiedMessage = message.decode().upper()
    serverSocket.sendto( modifiedMessage.encode(),clientAddress)

首先与client的代码不同的是:

serverSocket.bind(('',serverPort))

这行代码将端口号显示的绑定在套接字上,等待客户端的请求,任何人发送到12000端口号都可以被接收,然后进入一个死循环

while True:
    message,clientAddress = serverSocket.recvfrom(2048)
    modifiedMessage = message.decode().upper()
    serverSocket.sendto( modifiedMessage.encode(),clientAddress)

此循环允许服务器无限期的接收并处理来自客户端的分组,在while循环中,UDPserver等待一个分组到达。

TCP实现

首先介绍一下,与UDP不同,TCP是一个面向连接的运输层协议,也就是在服务器和客户端相互通信之前必须连接完成(具体就是三次握手),当客户端和服务器的套接字建立连接以后,我们可以往套接字里丢数据,不用向UDP一样附带目的地的地址。
三次握手建立连接期间,客户进程敲服务器的欢迎之门,当服务器监听到敲门声时,它将生成一个新的套接字 ,专门用于特定的客户!这个专门用于处理客户的套接字叫做连接套接字,这里要弄清楚!示意图:
在这里插入图片描述
下图展示了客户端与服务器的主要与套接字相关的活动,两者通过TCP运输服务进行通信:
在这里插入图片描述
看一下TCPClient的代码设计:

// TCPClient.py
from socket import *
serverName = 'servername'
serverPort = 12000
clientSocket = socket(AF_INET,SOCK_STREAM)
clientSocket.connect((serverName,serverPort))
sentence = raw_input('Input lowerase sentence:')
clientSocket.send(sentence.encode())
modifiedSentence = clientSocket.recv(1024)
print('From Server:',modifiedSentence.decode())
clientSocket.close()

代码解释:
前三行和前面的UDP连接时候一样的功能,设定服务器名字和端口号,去连接,下面socket也是创建套接字,但是不同的是第二个参数:

clientSocket = socket(AF_INET,SOCK_STREAM)

SOCK_STREAM参数是指创建一个TCP的套接字,这个网络通信就基于TCP运输层进行传递消息。

clientSocket.connect((serverName,serverPort))

这里就是TCP连接的特点和重点,就是面向连接的运输层协议,connect函数向服务器ip和端口号进行连接请求,这里进行了三次握手。

sentence = raw_input('Input lowerase sentence:')

这里就是python的内置函数,等待输入一行字符并且以字符串提醒。

clientSocket.send(sentence.encode())

这里又是与UDP不同的地方,不用输入地址和端口号,因为已经建立了连接,用户只需要向建立的TCP连接中丢数据就可以了,这里将sentence发送给了服务端。

modifiedSentence = clientSocket.recv(1024)
print('From Server:',modifiedSentence.decode())
clientSocket.close()

这里接收来自服务端的消息,打印,关闭套接字。与UDP类似。

下面写一下TCP的服务端代码

// TCPServer.py
from socket import *
severPort = 12000
serverSocket = socket(AF_INET,SOCK_STREAM)
serverSocket.bind(('',serverPort))
serverSocket.listen(1)
print('The server is ready to receive')
while True 
      connectionSocket,addr=serverSocket.accept()
      sentence = connectionSocket.recv(1024).decode()
      capitalizedSentence = sentence.upper()
      connectionSocket.close()

代码解释:
前四行与UDP没有什么不同,建立套接字,同时绑定定义好的端口号给套接字。

serverSocket.listen(1)

这里的listen是让套接字(欢迎套接字)监听端口号,参数1定义了请求的最大连接数,这里只允许同时接待一个客户端连接请求。

while True 
      connectionSocket,addr=serverSocket.accept()
      sentence = connectionSocket.recv(1024).decode()
      capitalizedSentence = sentence.upper()
      connectionSocket.close()

当有用户来敲门,被监听套接字所接收,服务器会创建一个新socket名为connectionSocket,用来做连接套接字,为此客户专用,客户与服务器则完成了握手并且建立了连接套接字,可以通过这个连接相互传递消息,最后关闭套接字。

上面就复习了一下关于UDP和TCP的套接字编程模式。
bye~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值