IP地址:在互联网上,要允许任何两台主机与任何其他的主机进行通讯,TCP/IP为每台主机分配了一个唯一的32位数字,即IP地址,IP地址对网上的某个节点来说是一个逻辑地址,它独立于任何特定的网络硬件和网络配置,IP地址由网络号和主机号两部分组成。
SOCKET:也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。应用程序通过“套接字”向网络发出请求或应答网络请求。socket是最基础的网络协议,htttp/ftp等都应用层的网络协议都是用socket写的。socket有不同类型,SOCK_STREAM(TCP)、SOCK_DGRAM(UDP)、SOCK_RAW(无法处理ICMP和IGMP等网络报文)
SOCKET通讯
开发者创建“服务器”与“客户端”两个应用程序,通过网络实现进程间的通讯。
服务器端流程:创建套接字(socket)——绑定到一个地址和端口(bind)——侦听进来的连接(listen)——处理新到连接(accept)——数据收发(receive/send)——套接字关闭(close)
客户端流程:创建套接字(socket)——连接到一个地址和端口(connect)——数据发收(send/receive)——套接字关闭(close)
# -*- coding: utf-8 -*-
import socket
HOST='' #空表示localhost
PORT=20187
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#AF_INET地址族,SOCK_STREAM数据报文协议
s.bind((HOST,PORT)) #bind参数一个,元组
s.listen(1)
conn,addr=s.accept() #如果没有客户端连接,程序执行到这里阻塞
#conn是为要连接服务器端的客户端创建实例,后续通讯通过该实例交互
#addr是客户端的地址
print 'Connected by',addr
while 1:
data=conn.recv(1024)
if not data:break #如果没有数据,说明客户端已经断开,跳出程序
conn.sendall(data.upper()) #把收到的数据全部再发回去
conn.close()
# -*- coding: utf-8 -*-
import socket
HOST='127.0.0.1' #服务器端地址
PORT=20187 #端口号与服务器端一致
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((HOST,PORT)) #连接
s.sendall('Hello,world')
data=s.recv(1024)
s.close()
print 'Received',data
Python的web框架:
(1)自己写socket(请求来了交给函数handle_request),自己处理请求
e.g.自己写的,Tornado
(2)基于wsgi(内部写了个socket的web服务网关接口)(请求来了交给函数RunServer),自己处理请求
e.g.Django,Flask
HTTP通讯
HTTP请求是短连接,socket客户端和服务端请求答复一次,连接就断开。
# coding:utf-8
import socket
def handle_request(client): #自己写socket,处理请求的函数
buf = client.recv(1024)
client.send("HTTP/1.1 200 OK\r\n\r\n")
client.send("Hello, SOCK")
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 8000))
sock.listen(5)
while True:
connection, address = sock.accept()
handle_request(connection)
connection.close()
if __name__ == '__main__':
main()
# coding:utf-8
from wsgiref.simple_server import make_server
def RunServer(environ, start_response): #wsgi对预处理结果,执行RunServer方法处理请求
start_response('200 OK', [('Content-Type', 'text/html')])
return '<h1>Hello, web!</h1>'
if __name__ == '__main__':
httpd = make_server('', 20180, RunServer)
print("Serving HTTP on port 20180...")
httpd.serve_forever() #浏览器发来请求后,先接受请求,再预处理请求(封装http请求)