套接字及其方法
套接字是双向通信通道的端点。它们可以在进程内、同一机器上的进程之间或不同机器上的进程之间进行通信。类似地,网络套接字是在计算机网络(例如 Internet)上运行的两个程序之间的通信流中的一个端点。它纯粹是一个虚拟的东西,不代表任何硬件。网络套接字可以通过 IP 地址和端口号的唯一组合来标识。网络套接字可以通过许多不同的通道类型(例如 TCP、UDP 等)来实现。
网络编程中使用的与套接字相关的不同术语如下:
领域
域是用作传输机制的协议族。这些值是常量,例如 AF_INET、PF_INET、PF_UNIX、PF_X25 等。
类型
类型表示两个端点之间的通信类型,通常为面向连接的协议的 SOCK_STREAM 和无连接协议的 SOCK_DGRAM。
协议
这可用于识别域和类型内协议的变体。它的默认值为 0。这通常被忽略。
主机名
它用作网络接口的标识符。主机名可以是字符串、点分四组地址或冒号(也可能是点)表示法的 IPV6 地址。
港口
每台服务器都会监听一个或多个端口上的客户端调用。端口可以是 Fixnum 端口号、包含端口号的字符串或服务名称。
Python 的 Socket 模块用于套接字编程
要在python中实现socket编程,我们需要使用Socket模块。以下是创建 Socket 的简单语法 -
import socket s = socket.socket (socket_family, socket_type, protocol = 0)
这里,我们需要导入socket库,然后制作一个简单的socket。以下是创建套接字时使用的不同参数 -
socket_family - 这是 AF_UNIX 或 AF_INET,如前所述。
socket_type - 这是 SOCK_STREAM 或 SOCK_DGRAM。
协议- 这通常被忽略,默认为 0。
套接字方法
在本节中,我们将了解不同的套接字方法。下面描述了三组不同的套接字方法 -
- 服务器套接字方法
- 客户端套接字方法
- 通用套接字方法
服务器套接字方法
在客户端-服务器架构中,有一台集中式服务器提供服务,许多客户端从该集中式服务器接收服务。客户端也向服务器发出请求。该架构中的一些重要的服务器套接字方法如下 -
socket.bind() - 此方法将地址(主机名、端口号)绑定到套接字。
socket.listen() - 此方法基本上侦听与套接字建立的连接。它启动 TCP 侦听器。Backlog 是此方法的一个参数,它指定排队连接的最大数量。其最小值为 0,最大值为 5。
socket.accept() - 这将接受 TCP 客户端连接。(conn,address)对是该方法的返回值对。这里,conn是一个新的socket对象,用于在连接上发送和接收数据,address是绑定到socket的地址。在使用该方法之前,必须使用socket.bind()和socket.listen()方法。
客户端套接字方法
客户端-服务器架构中的客户端向服务器请求并接收来自服务器的服务。为此,只有一种专用于客户的方法 -
socket.connect(address) - 此方法主动建立服务器连接,或者简单地说,此方法将客户端连接到服务器。参数地址表示服务器的地址。
通用套接字方法
除了客户端和服务器套接字方法之外,还有一些通用套接字方法,它们在套接字编程中非常有用。一般套接字方法如下 -
socket.recv(bufsize) - 顾名思义,此方法从套接字接收 TCP 消息。参数 bufsize 代表缓冲区大小,定义该方法在任一时间可以接收的最大数据。
socket.send(bytes) - 此方法用于将数据发送到连接到远程计算机的套接字。参数 bytes 将给出发送到套接字的字节数。
socket.recvfrom(data, address) - 此方法从套接字接收数据。此方法返回两对(数据、地址)值。Data定义了接收到的数据,address指定了发送数据的socket地址。
socket.sendto(data, address) - 顾名思义,此方法用于从套接字发送数据。此方法返回两对(数据、地址)值。数据定义发送的字节数,地址指定远程机器的地址。
socket.close() - 此方法将关闭套接字。
socket.gethostname() - 此方法将返回主机的名称。
socket.sendall(data) - 此方法将所有数据发送到连接到远程计算机的套接字。它会不小心地传输数据,直到发生错误,如果发生错误,它会使用 socket.close() 方法关闭套接字。
建立服务器和客户端之间的连接的程序
为了建立服务器和客户端之间的连接,我们需要编写两个不同的Python程序,一个用于服务器,另一个用于客户端。
服务器端程序
在这个服务器端套接字程序中,我们将使用socket.bind()方法将其绑定到特定的 IP 地址和端口,以便它可以侦听该 IP 和端口上的传入请求。稍后,我们使用socket.listen()方法将服务器置于监听模式。数字(例如 4)作为socket.listen()方法的参数意味着,如果服务器繁忙,则 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'+ "\r\n" conn.send(msg.encode('ascii')) conn.close() if __name__ == '__main__': Main()
客户端程序
在客户端socket程序中,我们需要制作一个socket对象。然后我们将连接到服务器运行的端口 - 在我们的示例中为 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 块,如果服务器和客户端之间未建立连接,它将打印一条消息。