标签:别人 一个 打电话 ase oca 属性 交互 直接 计算
‘‘‘ 网络通信用于获取一个算法在本地运行所需的数据,还可以共享信息实现分布式处理,另外可以用来管理云服务。 python的标准库提供了一些模块来创建网络服务以及访问现有服务 ipaddress模块提供了一些类来验证、比较和处理IPV4/IPV6网络地址 底层socket库允许直接访问原生C套接字库,可以用于与任何网络服务通信。 selectors提供了一个高层接口,可以同时监视多个套接字,这对于支持网络服务器同时与多个客户通信很有用。select提供了selectors使用的底层API socketserver中的框架抽象了创建一个新的网络服务器所需要的大量重复性工作。 可以结合这些类创建服务器来建立或使用线程以及支持TCP或UDP。应用只需要完成实际的消息处理 ‘‘‘
‘‘‘ ipaddress模块提供了处理IPV4和IPV6网络地址的类。这些类支持验证,查找网络上的地址和主机,以及其他常见操作 ‘‘‘
import binascii import ipaddress ‘‘‘ 最基本的对象表示网络地址本身。可以像ip_address函数传入一个字符串,整数或者字节序列来构造一个地址。 返回值是一个IPv4Address或IPv6Address实例,这取决于使用什么类型的地址 ‘‘‘ address = "61.135.169.125" addr = ipaddress.ip_address(address) print(addr) print(f"ip version: {addr.version}") print(f"is private: {addr.is_private}") print(f"packed form: {binascii.hexlify(addr.packed)}") print(f"integer: {int(addr)}") ‘‘‘ 61.135.169.125 ip version: 4 is private: False packed form: b‘3d87a97d‘ integer: 1032300925 ‘‘‘
import socket ‘‘‘ socket包含一些与网络上的域名服务交互的函数,这使得程序可以将服务器的主机名转换为数字网路地址。 应用使用地址链接服务器之前并不需要显式地转换地址,不过报告错误时除了报告所用的名字之外,如果还能包含这个数字地址,那么便会很有用 ‘‘‘ # 要查找当前主机的正式名,可以使用gethostname函数 print(socket.gethostname()) # WINDOWS-JTP7CGR # 还可以使用gethostbyname函数根据主机名获取ip地址 print(socket.gethostbyname(socket.gethostname())) # 192.168.0.110 # 不仅如此,还可以根据url,找出网站的ip。 # 总所周知,我们访问百度,可以通过www.baidu.com,但是我们是通过这个域名来访问百度的ip地址,只是ip比较难记罢了 # 我们也可以根据url找到对应网站的ip print(socket.gethostbyname("www.baidu.com")) # 61.135.169.125 # 如果想访问更多的信息,可以使用这个函数 name, aliases, addressed = socket.gethostbyname_ex("www.baidu.com") print(name) # www.a.shifen.com print(aliases) # [‘www.baidu.com‘] print(addressed) # [‘61.135.169.121‘, ‘61.135.169.125‘]
import socket ‘‘‘ 除了ip地址之外,每个套接字地址好包括一个整数端口号。 很多应用可以在同一个主机上运行并监听一个ip地址,不过只有一个套接字可以使用该地址的端口。 通过结合ip地址、协议和端口号,可以唯一地标识一个通信通道,并确保通过一个套接字发送的消息能到达正确的目标 有些端口号已经预先分配给特定的协议。例如,使用SMTP的email服务器使用TCP在端口25完成通信,web客户和服务器使用端口80完成HTTP通信。 ‘‘‘ # 可以使用getservbyname方法查找网络服务的端口号和标准名 print(socket.getservbyname("http")) # 80 print(socket.getservbyname("https")) # 443 print(socket.getservbyname("ftp")) # 21 print(socket.getservbyname("smtp")) # 25 # 也可以使用getservbyport根据端口号查找协议 print(socket.getservbyport(80)) # http print(socket.getservbyport(666)) # doom
import socket ‘‘‘ getaddrinfo函数将一个服务的基本地址转换为一个元组列表,其中包含建立一个连接所需的全部信息。每个元组可能包含不同的网络簇或协议 ‘‘‘ res = socket.getaddrinfo("www.baidu.com", "https") print(res) # [(<AddressFamily.AF_INET: 2>, 0, 0, ‘‘, (‘61.135.169.125‘, 443)), (<AddressFamily.AF_INET: 2>, 0, 0, ‘‘, (‘61.135.169.121‘, 443))]
import socket # 创建tcp/ip套接字,这里作为服务端 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定ip和端口,客户端连接这个ip和端口就可以向我们这里的服务端发送消息 # 这里要传入元组 server.bind(("localhost", 8888)) # 同时监听多少个到来的链接,也就是一次最多可以让多少个客户连接 # 虽然可以监听多个链接,但是一次性只能处理一个。 # 比如监听5,表示接收5个链接,当来了5个链接,并不是同时处理5个,而是一次性处理一个,其他的4个要排队。而再来第6个链接连队也不让排了,直接拒绝接收了 server.listen(5) # 创建循环,表示一个链接关闭了,继续循环处理下一个链接 while True: # accept:等待客户端的链接,一旦到来,就会与之交互 # 会有两个返回值。conn:客户端与服务端之间建立的一个链接。addr:客户的地址 # 这个过程是会阻塞的 conn, addr = server.accept() # 创建循环,因为消息不止发送一次,会多次来回发送,你一句我一句,直到没话了,结束循环 # 从而执行外层循环,等待下一个链接,然后继续循环你一句我一句 while True: # 发送消息和接收消息都是conn这个链接实例去执行的 # recv表示接收数据,1024表示最多一次性最多接收1024个字节 data = conn.recv(1024) # 如果对方断开链接了,那么发送的数据就为空了 # 所以要进行判断,如果得到的数据为空,那么就break,也就是断开当前的链接 if not data: print(f"客户端{addr}:断开链接") break # 有数据的话,那么打印出来 print(str(data, encoding="utf-8")) # 同时也给客户端发送数据 conn.sendall(data + bytes(" 我收到了", encoding="utf-8")) # 清理链接,进行资源、端口的释放等等 conn.close()
import socket # 我们是客户端,所以要创建一个绑定到指定ip和端口的链接 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 这里不再是bind了,而是connect,因为我们不是创建服务器等待链接,而是客户端,要绑定指定的链接去连接别人 client.connect(("localhost", 8888)) while True: # 发送数据,到时候服务端也会回数据 client.sendall(bytes(input("你要发送的数据:"), encoding="utf-8")) data = client.recv(1024) print(str(data, encoding="utf-8"))
可以看到,这里还有一个不完美的地方,那就是当客户端断开链接时,服务端报错了,这要咋办呢?可以在第二层循环来一个异常捕获就行了
标签:别人 一个 打电话 ase oca 属性 交互 直接 计算
原文地址:https://www.cnblogs.com/traditional/p/10617030.html