夜间模式暗黑模式
字体
阴影
滤镜
圆角

Category: Backend

2 篇文章

thumbnail
随便整理一下web开发相关
[toc] 连接是一件单纯的事情,让连接能够产生绚丽多彩的东西就是不简单的事情。Web开发,差不多就是在干绚丽多彩的事情,重点不在connected的结果,而是connected后的画面。 1 架构的转变 在以前的应用软件都是运行在大型机上面,要使用软件就要通过“哑终端”登录到大型机上去操作软件。什么叫做哑终端呢?就是字符终端,只具备输入输出字符的功能。这时候软件和数据都集中在大型机上。 后来兴起了Personal Computer,软件开始运行在桌面上,和现在的情况类似。而那些软件需要的数据则由远程的服务器存储,服务器端运行像数据库这样的软件。这种模式称为CS架构,也就是客户端和服务器(Client/Server)架构。 客户端和服务器(Client/Server)架构 随着互联网的不断发展,发现CS架构并不是太适合Web应用。主要原因是Web内容更新太快,而若是采用CS架构则需要客户端不停地同步更新桌面应用。后来的浏览器和服务器模式(Brower/Server)应用广泛,在客户端下只要通过浏览器向服务器请求,获取Web内容,并将其显示在浏览器上即可。 浏览器和服务器模式(Brower/Server) 2 Web开发是组啥的? 还记得我之前说的一个词“绚丽多彩”吗,Web开发就是干绚丽多彩的事情的。然而并不是全部。可以把Web分为前端后端,但我觉得要是从事Web开发,一定要冲着全栈的方向去发展自己。表面来看,Web前端更加能够接近绚丽多彩的意思,而后端,甚至是一些Web框架的开发,都是枯燥无味的。但是没有框架也就没有绚丽多彩了。这之间的关系相信读者能够十分轻易的揣摩出来。 3 Web应用开发阶段 3.1 静态阶段 直接编写html文件,如果需要更新则要重新修改原html文件 3.2 交互阶段 静态阶段的网页无法和用户进行交互,如果用户在某个网站上有注册用户的需求,必定会提交一个注册表单。但是静态页面是无法处理这样的数据。CGI(Common Gateway Interface)通用网关接口的出现,使得网页处理动态数据成为了可能。 3.3 脚本阶段 Web应用的特点在前面也提到过,就是更新频繁。在交互阶段的CGI中编写语言都是采用C/C++这样的低级语言,使得开发非常不方便。而因为脚本语言和html结合紧密,且本身非常适合用来开发,因而迅速取代了CGI。常见的脚本语言有ASP/JSP/PHP。 ASP(Active Server Pages)是微软自家开发的服务器端脚本环境,JSP(Java Server Pages)实现了html语法中的Java扩展,PHP(Hypertext Preprocessor)这是一种通用的开源脚本语言。 3.4 MVC阶段 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。MVC解决的脚本语言直接嵌入html所带来的开发问题,实现了业务逻辑、数据和界面相分离的方法。将业务逻辑全部聚集在一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑,因此可以显著简化Web开发。目前的脚本语言都有很多兼容的MVC框架。 MVC 3.5 现阶段 Web开发不断发展中,诸如MVVC、MVVM、异步开发层出不穷。 MVVM
thumbnail
简单的网络连接实验
[toc] 怎么来模拟一下我们日常的网络连接呢? 网络连接首先要理解成为信息数据的传输。在传输层中我们需要符合一些“规则”,让数据们“符合规范”,才能在网络中进行传输,这也是理所当然且可以理解的事情。一旦没有了规则,做什么事都会乱套。 一般有两套规则可以使用:TCP和UDP协议。 1 什么叫TCP呢? TCP(Transmission Control Protocol),叫做传输控制协议,是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来,也就是俗称的“三次握手”。三次握手简单来说是这样的:A向B发出连接请求数据包:“我想给你发数据,可以吗?”,这是第一次对话;B向A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:“可以,你什么时候发?”,这是第二次对话;A再发出一个数据包确认B的要求同步:“我现在就发,你接着吧!”,这是第三次对话。三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后,A才向B正式发送数据。 归纳一下,就是TCP规则下,双方先试着传一下数据看看能否接受同步,如果可以就认为是建立好连接了,接下来就可以正式进行数据的传输。 2 什么叫UDP呢? UDP(User Data Protocol,用户数据报协议)应该和TCP差不多都是一种数据传输规则。差别在于UDP是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去! UDP适用于一次只传送少量数据、对可靠性要求不高的应用环境。比如,我们经常使用“ping”命令来测试两台主机之间TCP/IP通信是否正常,其实“ping”命令的原理就是向对方主机发送ICMP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。例如,在默认状态下,一次“ping”操作发送4个数据包(可以在cmd中执行ping www.endcat.cn)。可以看到,发送的数据包数量是4包,收到的也是4包(因为对方主机收到后会发回一个确认收到的数据包)。这充分说明了UDP协议是面向非连接的协议,没有建立连接的过程。正因为UDP协议没有连接的过程,所以它的通信效率高;但也正因为如此,它的可靠性不如TCP协议高。QQ就使用UDP发消息,因此有时会出现收不到消息的情况。 3 接下来我们来模拟吧 3.1 TCP连接模拟 3.1.1 首先要知道一下Socket是什么东西 谷歌翻译socket是插座的意思?!但是好像在网络编程里面并不是“插座”的意思鸭… 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。等一下插座这个意思可以解释的通。想象一下哈,我们有两台主机,各自带有一个插孔(插孔就是Socket啦),现在又有一条两端都是插头的绳子,两端插在两台主机上面使得主机之间可以通信。这条绳子就差不多是像网线一样的东西吧,应该是这样的(自言自语)。所以建立网络通信连接至少要一对端口(socket)。 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。句柄就是当一个应用程序要引用其他系统(如数据库、操作系统)所管理的内存块或对象时,就要使用句柄来工作。 在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原义那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务。 3.1.2 简单的TCP客户端(Client) 客户端是什么意思?简单的来说,主动发起连接的就是客户端,被动接受连接的就是服务器(server) 。举个例子,当我们在浏览器中访问网站时,我们自己的计算机就是客户端,浏览器会主动向网站的服务器发起连接。如果一切顺利,网站的服务器接受了我们的连接,一个TCP连接就建立起来的,后面的通信就是发送网页内容了。 既然要发起连接,前面说过了,我们应该要有一个socket,这样才能和远程网站服务器的socket进行连接,这样我们才能看到网站的信息。 所以接下来我们要模拟创建一个socket。 #利用python来创建一个socket #首先导入一个socket库,里面提供了创建socket的必要函数 import socket #创建一个socket,名字叫做s s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #开始建立连接 s.connect(('127.0.0.1', 9999)) #接受数据并把它们打印出来 print(s.recv(1024).decode('utf-8')) #从客户端发送给服务器一些数据 for data in [b'Aumi', b'Endcat']: s.send(data) print(s.recv(1024).decode('utf-8')) #发送一个exit信息,表示我要退出连接辽 s.send(b'exit') #关闭socket,本次连接结束 s.close() 有几点地方要注意一下: connect函数要注意参数是一个元组tuple,包含地址和端口号。 端口号小于1024的是Internet标准服务的端口,可能需要管理员权限。端口号大于1024的,可以任意使用。 创建socket时,AF_INET指定使用IPv4协议,如果要用更先进的IPv6,就指定为AF_INET6。SOCK_STREAM指定使用面向流的TCP协议,这样,一个socket对象就创建成功,但是还没有建立连接。 127.0.0.1是一个特殊的IP地址,表示本机地址,如果绑定到这个地址,客户端必须同时在本机运行才能连接,也就是说,外部的计算机无法连接进来。接收数据时,调用recv(max)方法,一次最多接收指定的字节数 . 3.1.3 简单的TCP服务器(Server) 现在假设我们是一个服务器了,我们需要接受远程客户端发来的连接请求。不管怎么说,创建socket是头等大事,之后我们要按照对方发来的数据进行分析,并返回给客户端数据。 #引用一些库,某些不一样的地方会在后面提示 import socket import threading import time #新线程的函数 def tcplink(sock, addr): print('Accept new connection from %s:%s...' % addr) #发送一个欢迎标识 sock.send(b'Welcome!') #死循环接受客户端数据 while True: data = sock.recv(1024) #哦,在这里停顿一下 time.sleep(1) #如果没有数据或者接收到了exit,那么就跳出循环 if not data or data.decode('utf-8') == 'exit': break #发送打招呼的数据 sock.send(('Hello, %s' % data.decode('utf-8')).encode('utf-8')) #关闭连接,本次连接结束 sock.close() print('Connection from %s:%s closed.' % addr) #创建一个socket对象,还是熟悉的味道 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #绑定接口,注意参数tuple s.bind(('127.0.0.1', 9999)) #开始监听有无数据到达,参数表示最大等待链接数量 s.listen(5) print('Waiting for connection...') #死循环接受客户端连接 while True: #接收到了客户端请求 sock, addr = s.accept() #创建一个线程来处理改客户端数据,多线程可以同时处理不同客户端的请求 t = threading.Thread(target=tcplink, args=(sock, addr)) t.start() 3.1.4 开始连接尝试 可以打开两个终端,先运行server再运行client,看看两个终端各自返回了什么信息。接下来的UDP也是同理哦。 3.2 UDP连接模拟 相比TCP,感觉UDP更加简单一点。其实原因也是显而易见的,前面说过UDP是不讲究连接的可靠性而是直接把数据发送过去。在代码量上也可以看出UDP更加简单。 3.2.1 简单的UDP客户端(Client) import socket #DGRAM指定了UDP s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) for data in [b'Endcat', b'Aumi']: #不需要connect,直接使用sendto发送数据 s.sendto(data, ('127.0.0.1', 9999)) print(s.recv(1024).decode('utf-8')) s.close() 3.2.2…