套接字及其方法
套接字是双向通信通道的端点。它们可以在进程内、同一台机器上的进程之间或不同机器上的进程之间进行通信。同样,网络套接字是通过计算机网络(如 Internet)运行的两个程序之间的通信流的一个端点。它纯粹是虚拟的,并不意味着任何硬件。网络套接字可以通过 IP 地址和端口号的唯一组合来标识。网络套接字可以通过多种不同的通道类型实现,如 TCP、UDP 等。
网络编程中使用的与套接字相关的不同术语如下 −
域
域是用作传输机制的协议系列。这些值是常量,例如 AF_INET、PF_INET、PF_UNIX、PF_X25 等等。
类型
类型表示两个端点之间的通信类型,通常 SOCK_STREAM 用于面向连接的协议,SOCK_DGRAM 用于无连接协议。
协议
这可用于识别域和类型中的协议变体。其默认值为 0。通常省略。
主机名
这用作网络接口的标识符。主机名可以是字符串、点分四组地址或冒号(也可能是点)表示法中的 IPV6 地址。
端口
每个服务器侦听一个或多个端口上的客户端调用。端口可以是 Fixnum 端口号、包含端口号的字符串或服务名称。
用于套接字编程的 Python 套接字模块
要在 Python 中实现套接字编程,我们需要使用套接字模块。以下是创建套接字 − 的简单语法
import socket s = socket.socket (socket_family, socket_type, protocol = 0)
在这里,我们需要导入套接字库,然后创建一个简单的套接字。以下是创建套接字 − 时使用的不同参数
socket_family − 如前所述,这可以是 AF_UNIX 或 AF_INET。
socket_type −这可以是 SOCK_STREAM 或 SOCK_DGRAM。
protocol − 这通常被忽略,默认为 0。
套接字方法
在本节中,我们将了解不同的套接字方法。下面描述了三组不同的套接字方法 −
- 服务器套接字方法
- 客户端套接字方法
- 通用套接字方法
服务器套接字方法
在客户端-服务器架构中,有一个提供服务的集中式服务器,许多客户端从该集中式服务器接收服务。客户端也向服务器发出请求。此架构中的一些重要服务器套接字方法如下 −
socket.bind() − 此方法将地址(主机名、端口号)绑定到套接字。
socket.listen() − 此方法基本上监听与套接字建立的连接。它启动 TCP 侦听器。Backlog 是此方法的一个参数,它指定排队连接的最大数量。其最小值为 0,最大值为 5。
socket.accept() − 这将接受 TCP 客户端连接。pair (conn, address) 是此方法的返回值对。这里,conn 是一个新的套接字对象,用于在连接上发送和接收数据,address 是绑定到套接字的地址。使用此方法之前,必须使用 socket.bind() 和 socket.listen() 方法。
客户端套接字方法
客户端-服务器架构中的客户端向服务器发出请求并从服务器接收服务。为此,只有一种专用于客户端的方法 −
socket.connect(address) − 此方法主动建立服务器连接,或者简单地说,此方法将客户端连接到服务器。参数 address 表示服务器的地址。
通用套接字方法
除了客户端和服务器套接字方法外,还有一些通用套接字方法,它们在套接字编程中非常有用。通用套接字方法如下 −
socket.recv(bufsize) −顾名思义,该方法从套接字接收 TCP 消息。参数 bufsize 代表缓冲区大小,定义该方法一次可以接收的最大数据量。
socket.send(bytes) − 该方法用于将数据发送到连接到远程计算机的套接字。参数 bytes 将给出发送到套接字的字节数。
socket.recvfrom(data, address) − 该方法从套接字接收数据。该方法返回两对 (data, address) 值。Data 定义接收到的数据,address 指定发送数据的套接字的地址。
socket.sendto(data, address) − 顾名思义,该方法用于从套接字发送数据。该方法返回两对 (data, address) 值。数据定义发送的字节数,地址指定远程计算机的地址。
socket.close() − 此方法将关闭套接字。
socket.gethostname() − 此方法将返回主机的名称。
socket.sendall(data) − 此方法将所有数据发送到连接到远程计算机的套接字。它会粗心地传输数据,直到发生错误,如果发生错误,则使用 socket.close() 方法关闭套接字。
用于在服务器和服务器之间建立连接的程序客户端
要建立服务器和客户端之间的连接,我们需要编写两个不同的 Python 程序,一个用于服务器,另一个用于客户端。
服务器端程序
在此服务器端套接字程序中,我们将使用 socket.bind() 方法将其绑定到特定的 IP 地址和端口,以便它可以侦听该 IP 和端口上的传入请求。稍后,我们使用 socket.listen() 方法将服务器置于侦听模式。作为 socket.listen() 方法的参数的数字(例如 4)表示如果服务器繁忙,则 4 个连接将保持等待状态,如果第 5 个套接字尝试连接,则连接将被拒绝。我们将使用 socket.send() 方法向客户端发送消息。最后,我们分别使用 socket.accept() 和 socket.close() 方法发起和关闭连接。以下是服务器端程序 −
import socket def Main(): host = socket.gethostname() port = 12345 serversocket = socket.socket() serversocket.bind((host,port)) serversocket.listen(1) print('socket is listening') while True: conn,addr = serversocket.accept() print("Got connection from %s" % str(addr)) msg = 'Connecting Established'+ " " conn.send(msg.encode('ascii')) conn.close() if __name__ == '__main__': Main()
客户端程序
在客户端套接字程序中,我们需要创建一个套接字对象。然后我们将连接到服务器正在运行的端口 — 在我们的示例中为 12345。之后,我们将使用 socket.connect() 方法建立连接。然后通过使用 socket.recv() 方法,客户端将接收来自服务器的消息。最后,socket.close()方法将关闭客户端。
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = socket.gethostname() port = 12345 s.connect((host, port)) msg = s.recv(1024) s.close() print (msg.decode('ascii'))
现在,运行服务器端程序后,我们将在终端 − 上获得以下输出
socket is listening Got connection from ('192.168.43.75', 49904)
运行客户端程序后,我们将在其他终端上获得以下输出−
连接已建立
处理网络套接字异常
有两个块,即 try 和 except,可用于处理网络套接字异常。以下是用于处理异常的 Python 脚本 −
import socket host = "192.168.43.75" port = 12345 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: s.bind((host,port)) s.settimeout(3) data, addr = s.recvfrom(1024) print ("recevied from ",addr) print ("obtained ", data) s.close() except socket.timeout : print ("No connection between client and server") s.close()
输出
上述程序生成以下输出 −
No connection between client and server接
在上述脚本中,我们首先创建了一个套接字对象。然后提供运行服务器的主机 IP 地址和端口号 — 在我们的示例中为 12345。之后,使用 try 块,并在其中使用 socket.bind() 方法,我们将尝试绑定 IP 地址和端口。我们使用 socket.settimeout() 方法来设置客户端的等待时间,在我们的示例中,我们设置为 3 秒。如果服务器和客户端之间无法建立连接,则使用 except 块来打印一条消息。