一 网络编程三要素
包括:IP地址、端口和协议
其中:
1) IP地址:网络中每一台计算机的唯一标识,通过IP地址找到指定的计算机
2) 端口:用于标识进程的逻辑地址,通过端口找到指定进程
3) 协议:定义通信规则,符合协议则可以通信,不符合不能通信
二 socket
socket在所有语言中都是重要的网络编程知识点,而在Python中就有socket模块
socket模块中默认的参数:
family=AF_INET:用于服务器与服务器之间的网络通信 family=AF_INET6:基于IPV6方式的服务器与服务器之间的网络通信 type=SOCK_STREAM:基于TCP的流式socket通信 type=SOCK_DGRAM:基于UDP的数据报式socket通信
一般情况下都用的是IPV4
1) 通过TCP协议进行:
TCP服务端:
import socket
#1.创建socket对象
server=socket.socket()
#2.绑定ip和port
server.bind(('172.25.254.69',9009))
#3.监听客户端连接
server.listen()
print('服务端端口已经启动...')
#4.接收客户端连接
sockobj,address=server.accept()
while True:
#5.接收客户端发送的消息
recv_data=sockobj.recv(1024).decode('utf-8')
print('client:%s'%(recv_data))
if recv_data=='quit':
break
#6.给客户端回复消息
send_data=input('server: ')
if send_data=='quit':
break
sockobj.send(send_data.encode('utf-8'))
#7.关闭socket对象
server.close()
sockobj.close()
执行结果:
TCP客户端:
import socket
#1.创建socket对象
server=socket.socket()
#2.绑定ip和port
server.bind(('172.25.254.69',9009))
#3.监听客户端连接
server.listen()
print('服务端端口已经启动...')
#4.接收客户端连接
sockobj,address=server.accept()
while True:
#5.接收客户端发送的消息
recv_data=sockobj.recv(1024).decode('utf-8')
print('client:%s'%(recv_data))
if recv_data=='quit':
break
#6.给客户端回复消息
send_data=input('server: ')
if send_data=='quit':
break
sockobj.send(send_data.encode('utf-8'))
#7.关闭socket对象
server.close()
sockobj.close()
执行的结果:
客户端连接服务端,以此来实现通讯
程序只能连接一个客户端,并不能支持多并发,所以当出现第二个客户端时,就会出现挂起不动,所以想要完成多并发,可以通过前面提到的多协程来实现,当然还有其它的方法
TCP通过多协程来实现接收多个客户端:
import socket
from gevent import monkey
monkey.patch_all()
import gevent
def handle_requst(sockobj):
while True:
#5.接收客户端发送的消息
recv_data=sockobj.recv(1024).decode('utf-8')
print('client:%s'%(recv_data))
if recv_data=='quit':
break
#6.给客户端回复消息
send_data=input('server: ')
if send_data=='quit':
break
sockobj.send(send_data.encode('utf-8'))
#1.创建socket对象
server=socket.socket()
#2.绑定ip和port
server.bind(('172.25.254.69',9009))
#3.监听客户端连接
server.listen()
print('服务端端口已经启动...')
while True:
#4.接收客户端连接
sockobj,address=server.accept()
gevent.spawn(handle_requst,sockobj)
#7.关闭socket对象
server.close()
sockobj.close()
每一次接收客户端连接后,便开启一个协程,以此来实现同时接收多个客户端
2) 通过UDP协议进行
UDP服务端:
import socket
host='172.25.254.69'
port=9090
#1.创建socket对象
server=socket.socket(type=socket.SOCK_DGRAM)
#2.绑定ip和port
server.bind((host,port))
print('等待客户端的UDP连接...')
#3.接收客户端发送的消息
data,address=server.recvfrom(1024)
print('接收到的客户端消息为: ',data.decode('utf-8'))
print('客户端连接的socket地址: ',address)
#4.给客户端回复消息
server.sendto(b'hello client',address)
#5.关闭socket对象
server.close()
执行的结果:
UDP客户端:
import socket
host='172.25.254.69'
port=9090
#1.创建socket对象
client=socket.socket(type=socket.SOCK_DGRAM)
#2.发送消息给服务端
client.sendto(b'hello server',(host,port))
#3.接收服务端返回的消息
data,address=client.recvfrom(1024)
print('接收到的服务端消息: ',data.decode('utf-8'))
#4.关闭socket对象
client.close()
执行的结果:
执行结束,接收到服务端的连接成功通知
此时,服务端得到客户端的消息,以及IP地址和客户端连接的socket地址
三 通过socket获取网页内容
通过IP地址和端口号来对网页发送请求,获取简单的信息
import socket
client=socket.socket()
client.connect(('www.baidu.com',80))
client.send(b'GET / HTTP/1.1\r\nHost:www.baidu.com\r\nConnection: close\r\n\r\n')
recv_data=client.recv(1024*100)
print(recv_data.decode('utf-8'))
client.close()
执行的结果:
/home/kiosk/anaconda2/envs/2048/bin/python /home/kiosk/PycharmProjects/python/协程/11_获取网页内容.py
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: no-cache
Content-Length: 14615
Content-Type: text/html
Date: Mon, 08 Oct 2018 08:43:10 GMT
Etag: "5ba38008-3917"
Last-Modified: Thu, 20 Sep 2018 11:10:00 GMT
P3p: CP=" OTI DSP COR IVA OUR IND COM "
Pragma: no-cache
Server: BWS/1.1
Set-Cookie: BAIDUID=AE734014F5C6A5C24B8409768A128AFF:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BIDUPSID=AE734014F5C6A5C24B8409768A128AFF; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1538988190; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Vary: Accept-Encoding
X-Ua-Compatible: IE=Edge,chrome=1
Connection: close
<!DOCTYPE html><!--STATUS OK-->
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<link rel="dns-prefetch" href="//s1.bdstatic.com"/>
<link rel="dns-prefetch" href="//t1.baidu.com"/>
<link rel="dns-prefetch" href="//t2.baidu.com"/>
<link rel="dns-prefetch" href="//t3.baidu.com"/>
<link rel="dns-prefetch" href="//t10.baidu.com"/>
<link rel="dns-prefetch" href="//t11.baidu.com"/>
<link rel="dns-prefetch" href="//t12.baidu.com"/>
<link rel="dns-prefetch" href="//b1.bdstatic.com"/>
<title>百度一下,你就知道</title>
<link href="http://s1.bdstatic.com/
Process finished with exit code 0
得到的结果是一个html页面,可通过html对其解析