套接字及其方法

套接字是双向通信通道的端点。它们可以在进程内、同一台机器上的进程之间或不同机器上的进程之间进行通信。同样,网络套接字是通过计算机网络(如 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)

运行客户端程序后,我们将在其他终端上获得以下输出−

连接已建立

处理网络套接字异常

有两个块,即 tryexcept,可用于处理网络套接字异常。以下是用于处理异常的 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 块来打印一条消息。