编写web应用服务器报,TypeError: a bytes-like object is required, not ‘str’错误。
因为python2和python3的版本有些差异,而python3最重要的新特性也是对文本和二进制数据做了更清晰的区分。
文本用unicode编码,为str类型,二进制数据则为bytes类型
python2的例子
import socket,sys
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('www.madapapa.com',80))
#code=str.encode('GET /api.json HTTP/1.0\r\n\r\n')
#s.send(code)
s.send('GET /api.json HTTP/1.0\r\n\r\n')
while 1:
buf = s.recv(1000)
if not buf:
break
sys.stdout.write(buf)
s.close()
在python2的环境下运行,执行结果如下
python3的例子
import socket,sys
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('www.madapapa.com',80))
#s.send(str.encode('GET /api.json HTTP/1.0\r\n\r\n'))
s.send('GET /api.json HTTP/1.0\r\n\r\n'.encode())
while 1:
buf = s.recv(1000).decode()
#s1 = buf.decode()
if not buf:
break
sys.stdout.write(buf)
s.close()
在默认环境下运行(python3),执行结果如下
附录
套接字
套接字是一套用C语言写成的应用程序开发库,它首先是一个库。主要作用就是实现进程间通信和网络编程,因此在网络应用开发中被广泛使用。
套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。
在Python中可以基于套接字来使用传输层提供的传输服务,并以此进行开发网络应用。实际开发中使用的套接字可以分为三类:流套接字(TCP套接字)、数据报套接字和原始套接字。
流式套接字
流式套接字(SOCK-STREAM)。它提供了一种可靠的、可以进行双向连接的数据传输服务。其实现了数据无差错、无重复的发送。流式套接字自身便内设了流量控制功能。在TCP/IP协议簇中,使用TCP协议来实现字节流的传输,当用户想要发送大批量的数据或者对数据传输有较高的要求时,可以使用流式套接字。
数据报套接字
数据报套接字(SOCK-DGRAM)。它提供了一种不可靠的双向数据传输服务。数据包以独立的形式被发送,不提供可靠性保证。数据在传输过程中可能会丢失或重复,并且不能保证在接收端按发送顺序接收数据。在TCP/IP协议簇中,使用UDP协议来实现数据报套接字。在出现差错的可能性较小或允许部分传输出错的应用场合,可以使用数据报套接字进行数据传输,这样通信的效率较高。
原始套接字
原始套接字(SOCK-RAW)。该套接字允许对较低层协议(如IP或ICMP)进行直接访问,常用于网络协议分析,检验新的网络协议实现,也可用于测试新配置或安装的网络设备。
上述就是套接字的大体知识,对套接字有了一定的了解,我们就可以步入正题了。
TCP套接字
TCP套接字就是上面所说的流式套接字,可以使用TCP协议提供的传输服务来实现网络通信的编程接口。
在Python中可以通过创建socket对象并指定type属性为SOCK_STREAM来使用TCP套接字。
由于一台主机可能拥有多个IP地址,所以作为服务器端的程序,需要在创建套接字对象后将其绑定到指定的IP地址和端口上。
这个端口是指对IP地址的扩展,用于区分不同的服务。
不同的服务通常与相对的端口所绑定。
当服务器收到用户请求时就可以根据端口号来确定到底用户请求的是何种服务。
关于服务于端口的绑定类型,我们会在之后的开发的当中具体描述。
如何用Python设置一个客户端的功能,简易代码如下:
fromsocketimportsocket
def main():
1.创建套接字对象默认使用IPv4和TCP协议
client= socket()
2.连接到服务器 ,指定IP地址和端口
client.connect((‘192.168.1.8’, 1080))
3.从服务器接收数据
print(client.recv(1024).decode(‘utf-8’))
client.close()
if__name__ == ‘main‘:
main()
上述代码就实现了客户端的功能,它可以与服务器进行通信。当然,上述代码只能作为一个最简单的客户端构建方式。更复杂的构建方式,学记将在之后的学习中为大家继续介绍。