📜  套接字及其方法

📅  最后修改于: 2020-12-06 10:31:01             🧑  作者: Mango


套接字是双向通信通道的端点。它们可以在一个进程内,同一台机器上的进程之间或不同机器上的进程之间进行通信。类似地,网络套接字是在计算机网络(例如Internet)上运行的两个程序之间的通信流中的一个端点。它纯粹是虚拟的,并不意味着任何硬件。可以通过IP地址和端口号的唯一组合来标识网络套接字。网络套接字可以在许多不同的通道类型(如TCP,UDP等)上实现。

与网络编程中使用的套接字相关的不同术语如下-

域是用作传输机制的协议系列。这些值是常量,例如AF_INET,PF_INET,PF_UNIX,PF_X25等。

类型

类型表示两个端点之间的通信类型,对于面向连接的协议,通常为SOCK_STREAM;对于无连接协议,通常为SOCK_DGRAM。

协议

这可以用于识别域和类型内协议的变体。其默认值为0。通常将其忽略。

主机名

这用作网络接口的标识符。主机名可以是字符串,点分四进制地址或IPV6地址(以冒号(可能是点)表示)。

港口

每个服务器侦听在一个或多个端口上调用的客户端。端口可以是Fixnum端口号,包含端口号的字符串或服务名称。

用于套接字编程的Python套接字模块

要在Python实现套接字编程,我们需要使用Socket模块。以下是创建套接字的简单语法-

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侦听器。待办事项是此方法的参数,它指定排队的最大连接数。最小值为0,最大值为5。

  • socket.accept() -这将接受TCP客户端连接。该对(conn,address)是此方法的返回值对。在这里,conn是一个新的套接字对象,用于在连接上发送和接收数据,而address是绑定到套接字的地址。在使用此方法之前,必须使用socket.bind()和socket.listen()方法。

客户端套接字方法

客户端-服务器体系结构中的客户端请求服务器并从服务器接收服务。为此,只有一种专用于客户端的方法-

  • socket.connect(address) -此方法主动建立服务器连接,或者简单地说,此方法将客户端连接到服务器。参数地址代表服务器的地址。

通用套接字方法

除了客户端和服务器套接字方法外,还有一些常规的套接字方法,这些方法在套接字编程中非常有用。普通的套接字方法如下-

  • socket.recv(bufsize) -顾名思义,此方法从套接字接收TCP消息。参数bufsize代表缓冲区大小,并定义此方法可以随时接收的最大数据。

  • socket.send(bytes) -此方法用于将数据发送到连接到远程计算机的套接字。参数字节将给出发送到套接字的字节数。

  • socket.recvfrom(data,address) -此方法从套接字接收数据。此方法返回两对(数据,地址)值。数据定义接收到的数据,地址指定发送数据的套接字的地址。

  • socket.sendto(data,address) -顾名思义,此方法用于从套接字发送数据。此方法返回两对(数据,地址)值。数据定义发送的字节数,而地址指定远程计算机的地址。

  • socket.close() -此方法将关闭套接字。

  • socket.gethostname() -此方法将返回主机的名称。

  • socket.sendall(data) -此方法将所有数据发送到连接到远程计算机的套接字。它将不小心传输数据,直到发生错误为止,如果发生错误,它将使用socket.close()方法关闭套接字。

在服务器和客户端之间建立连接的程序

为了在服务器和客户端之间建立连接,我们需要编写两个不同的Python程序,一个用于服务器,另一个用于客户端。

服务器端程序

在此服务器端套接字程序中,我们将使用socket.bind()方法将其绑定到特定的IP地址和端口,以便它可以侦听该IP和端口上的传入请求。稍后,我们使用socket.listen()方法将服务器置于侦听模式。该数字(即4 )作为socket.listen()方法的参数表示,如果服务器繁忙且第5个套接字尝试连接,则4个连接将保持等待状态,然后连接将被拒绝。我们将使用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'+ "\r\n"
      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)

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

Connection Established

处理网络套接字异常

有两个块,即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块将打印一条消息。