套接字及其方法



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

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

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

类型

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

协议

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

主机名

这作为网络接口的标识符。主机名可以是字符串、点分四元组地址或冒号(可能还有点)表示法的IPV6地址。

端口

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

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

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

import socket
s = socket.socket (socket_family, socket_type, protocol = 0)

在这里,我们需要导入socket库,然后创建一个简单的套接字。以下是创建套接字时使用的不同参数:

  • **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客户端连接。对(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)值。Data定义发送的字节数,address指定远程机器的地址。

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

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

  • **socket.sendall(data)** - 此方法将所有数据发送到连接到远程机器的套接字。它将不间断地传输数据,直到发生错误,如果发生错误,则它使用socket.close()方法关闭套接字。

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

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

服务器端程序

在这个服务器端套接字程序中,我们将使用**socket.bind()**方法将其绑定到特定的IP地址和端口,以便它可以监听该IP和端口上的传入请求。稍后,我们将使用**socket.listen()**方法将服务器置于监听模式。例如,作为**socket.listen()**方法参数的数字4意味着如果服务器繁忙,则最多保持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

处理网络套接字异常

可以使用**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块用于在服务器和客户端之间未建立连接时打印消息。

广告
© . All rights reserved.