请选择 进入手机版 | 继续访问电脑版
 
深入浅出了解一下网络编程
VIEW CONTENTS
阅芽资讯 首页 技术分享 查看内容

深入浅出了解一下网络编程

2019-2-17 12:25| 发布者: 醉望月| 查看: 330| 评论: 0
摘要: 从TCP到Socket,彻底了解网络编程

从事开发编程的同学们,无论Web前端开发、Web后端开发,还是搜索引擎和大数据,简直一切的开发范畴都会触及到网络编程。比方我们停止Web效劳端开发,除了Web协议自身依赖网络外,通常还需求衔接数据库,而数据库衔接通常是经过网络衔接数据库效劳器,或者数据库集群,假如负载太高还要搞个缓存集群。

我们在上学的时候根本学了网络编程和网络协议。但两者之间的详细关系可能有些摸不到头脑。这里我们首先重点引见2个概念,一个概念是网络编程,另外一个是协议。

我们晓得网络协议是一个分层的协议族,也就是是有一组协议构成,从下往上各自傲责各自的功用。那什么是协议呢?协议的字面意义是共同计议,商议。简单的了解其实就是多方停止沟通的规则。而网络协议其实就是在网络中多个计算节点停止交互、沟通的规则。假如根我们日常生活比照的话,协议能够了解为言语,比方汉语普通话。两个人交流假如都用不通话,那么彼此都能了解对方表达的企图。例如,一个人用四川话,而另外一个用浙江话,那沟通起来估量简直不太可能。网络协议也是一样的,经过对数据格式的标准化,从而使计算机之间可以彼此明白对方的企图。

下面本文引见一下网络编程网络编程也称为socket编程,socket通常译作“套接字”,但原意其实意译应该为”接口“。也就是操作系统提供应开发人员停止网络开发的API接口。这套接口通常能够参数的调整支持多种协议,包括TCP、UDP和IP等等。下面本文从套接字编程和协议两方面分别细致的停止引见。

网络编程

为了便于了解,本文先从详细的内容开端,也就是经过一个实例引见一下网络编程是怎样回事。

本文将以TCP协议为例引见网络编程和协议之前的关系。为了简单,便于了解,本文以Python为例停止引见,假如不理解Python编程言语关系也不大,下面代码很容易了解。我们晓得在网络通讯中无论是BS架构还是CS架构,通常分为效劳端和客户端,只不过BS架构中的阅读器就是客户端。因而,本文的示例也包含效劳端和客户端2局部的代码。代码功用很简单,就是完成客户端和效劳端发送字符串。

从TCP到Socket,彻底了解网络编程是怎样回事

图1 客户端效劳端通讯模型

这个代码清单是效劳端的代码,这段代码的作用就是在效劳端的某个端口树立监听,并等候客户端树立衔接。完成衔接树立后,等候客户端发送数据,并将数据回传给客户端。

#!/usr/bin/env python3
#-*- coding:utf-8 -*-
from socket import *
from time import ctime
host = ''
port = 12345
buffsize = 2048
ADDR = (host,port)
# 创立一个基于TCP协议的套接字
tctime = socket(AF_INET,SOCK_STREAM)
tctime.bind(ADDR)
# 在指定的地址和端口监听
tctime.listen(3)
while True:
print('Wait for connection ...')
tctimeClient,addr = tctime.accept()
print("Connection from :",addr)
while True:
data = tctimeClient.recv(buffsize).decode()
if not data:
break
tctimeClient.send(('[%s] %s' % (ctime(),data)).encode())
tctimeClient.close()
tctimeClient.close()

阅读效劳端的代码能够看出主要包括,socket、bind、listen、accept、recv和send几个。其中值得关注的是listen和accept,两者分别用于监听端口和承受客户端的衔接恳求。

下面代码清单是客户端的完成,这里特别的中央是有一个connect函数,该函数完成与效劳端树立衔接。

#!/usr/bin/env python3
#-*- coding:utf-8 -*-
from socket import *
HOST ='localhost'
PORT = 12345
BUFFSIZE=2048
ADDR = (HOST,PORT)
tctimeClient = socket(AF_INET,SOCK_STREAM)
tctimeClient.connect(ADDR)
while True:
data = input(">")
if not data:
break
tctimeClient.send(data.encode())
data = tctimeClient.recv(BUFFSIZE).decode()
if not data:
break

print(data)
tctimeClient.close()

经过上述示例代码能够看出效劳端通常是被动的,而客户端则要主动一些。效劳端程序树立对某个端口的监听,等候客户端的衔接恳求。客户端向效劳端发送衔接恳求,不出不测的状况下衔接树立胜利,这时客户端和效劳端之前就能够互发数据了。当然,在实践消费环境中不测是经常的,因而从协议和接口层面,需求处置各种不测,本文在协议局部将细致引见。

另外,本文完成了一个根本的客户端和效劳端通讯的程序,这个形式的通讯在实践消费中简直不再运用。在实践消费中为了进步数据传输和处置的效率,通常采用异步形式,这些内容超出了本文的引见范围,后续文章会逐步引见。

TCP协议详解

前文说了网络协议是网络中不同计算机信息通讯的言语,为了完成交互,这个言语就需求有一定的格式。本文以TCP协议为例停止引见。

TCP协议是一个牢靠的传输协议,其牢靠性表如今2方面,一方面是保证数据包能够依照发送的次第抵达,另外一方面是保证数据包一定水平的正确性(后文详解为什么是一定水平上的正确性)。其牢靠性的完成则基于2点技术,一点是具有一个CRC校验,这样假如数据包中的某些数据呈现错误能够经过该校验和发现;另外一点是每个数据包都有一个序号,这样就能保证数据包的次第性,假如呈现错位的数据包能够恳求重发。

既然说到了格式,那我们先看一下TCP数据包的数据格式。如下图是TCP数据包的格式,包括原端口、目的端口、序列号和标识位等等内容,内容有些多,看着可能有点眼花。但从大的方面了解,这个数据包其实只包含2局部内容,一个是包头,另外一个则是详细需求传输的数据。在TCP协议的控制逻辑中,包头起着最为关键的作用,它是TCP协议中诸如树立衔接、断开衔接、重传和错误校验等各种特性的根底。

从TCP到Socket,彻底了解网络编程是怎样回事

图2 TCP数据包格式

包头的其它信息的含义都比拟明了,本文仅仅引见几个标志位(URG、ACK、PSH、RST、SYN和FIN)的含义。详细含义如下:

  • ACK: 确认序号有效。
  • RST:重置衔接
  • SYN:发起一个新衔接
  • FIN:释放一个衔接

衔接的树立

TCP在详细传输数据之前需求树立衔接。这里的衔接并不是物理衔接,物理衔接基于底层的协议曾经树立完成,而且TCP树立衔接也是要假定底层衔接曾经胜利,TCP的衔接其实是一个虚拟的,逻辑的衔接。简单粗暴的了解,就是客户端和效劳端分别记载了各自承受到的数据包的序号,并且将本身设置为某种状态。在TCP协议中,衔接的树立通常成为3次握手,从字面的概念能够看出,衔接的树立需求经过3次确认的过程。

从TCP到Socket,彻底了解网络编程是怎样回事

图3 树立衔接的3次握手

TCP协议3次握手的过程如图所示,初始状态客户端和效劳端都处于关闭状态。主要过程分为3步:

  1. 客户端发送预衔接数据包: TCP的衔接是由客户端主动发起树立,客户端会发送一个数据包(报文)给效劳端,需求留意的是数据包中的SYN标识位为1。我们前文曾经引见,假如SYN为1,则阐明为树立衔接的数据包。同时,在该数据包中包含一个恳求序列号,该序列号也是树立衔接的根据。
  2. 效劳端回复衔接确认: 效劳端确认能够树立衔接(效劳端不一定能够树立衔接,由于系统中套接字的数量是有限的)的状况下会向客户端发送一个应对数据包。在应对数据包中会将ACK标志位设置为1,表示为效劳端应对数据包。同时,在应对数据包中会设置恳求序列号和应对序列号的值,详细参考图3.
  3. 客户端回复衔接确认: 最后,客户端再次发送一个衔接确认数据包,通知效劳端衔接树立胜利。

从上面流程能够看出,衔接的树立需求经过屡次交互,这就是我们日常中所说的树立衔接是高本钱的操作。在实践消费环境中,为了应对这个问题,会减少衔接树立的频度,通常的做法是树立衔接池,传输数据时直接从衔接池中获取衔接,而不是新建衔接。

有人可能觉得能够对树立衔接的过程停止优化,比方将客户端最后一次确实认取消掉,觉得这个没有卵用。关于正常状况的确没有多大的作用,这里主要是应对异常状况。由于网络拓扑是十分复杂的,特别是在广域网中,有着数不清的网络节点,因而会呈现各种异常状况。因而,TCP协议在设计的时分必需要保证异常状况下的牢靠性。

我们这里举一个例子,就是衔接恳求超时的状况。假定客户端向效劳端发送一个衔接恳求,由于各种缘由,恳求不断没有抵达效劳端,因而效劳端也就没有回复衔接确认音讯。客户端衔接超时,因而客户端重新发送一个衔接恳求到效劳端,这次比拟顺利,很快抵达了,并且顺利树立了衔接。之后,前一个数据包经过长途跋涉最终还是到了效劳端,效劳端也向客户端发送了回复数据包,效劳端以为衔接是树立胜利的,并且会维持衔接。但客户端层面以为衔接是超时的,因而将永远不会关闭该衔接。这样就会形成效劳端有残留的资源,从而形成效劳端资源糜费,一朝一夕可能会招致效劳端无新衔接资源可用。

另外一个需求阐明的是客户端和效劳端的套接字都有相应的状态,而且状态会随着衔接的不同阶段变化。初始状态都是CLOSE,最终衔接树立胜利后都是ESTABLISHED,详细变化过程如图3所示。后面本文会细致引见状态变化状况。

传输数据

完成衔接树立之后,客户端和效劳端就能够停止数据传输了。我们晓得TCP是牢靠的传输,那么传输的牢靠性是经过什么来保证的呢?主要就是经过包头中的校验和、恳求序列号和应对序列号(参考图2)。

TCP数据内容的牢靠性是经过校验和保证的。TCP在发送数据时都会计算整个数据包的校验和,并存储在包头的校验和字段中。接纳方会依照规则停止计算,从而确认接纳到的数据能否是正确的。发送发计算校验和的流程大约如下:

  1. 把伪首部、TCP包头和TCP数据分为16为的字,并把TCP包头中的校验和字段置0
  2. 用反码加法累加一切16位数字
  3. 对计算结果去反,将其填充到TCP包头的校验和字段

接纳方将一切原码相加,高位叠加,假如全为1则表示数据正确,否则阐明数据有错误。

TCP数据包次第的牢靠性是经过恳求序列号和应对序列号保证的。在数据传输中的每个恳求都会有一个恳求序列号,而在接纳方接纳到数据后会发送一个应对序列号,这样发送方就能晓得数据能否被正确接纳,而接纳方也能晓得数据能否呈现乱序,从而保证数据包的次第性。

断开衔接

TCP关闭衔接分为4步,称为4次挥手。衔接的关闭不一定是在客户端发起,效劳端也能够发起关闭衔接。关闭衔接的过程如下:

  1. 发起方发送一个FIN置位的数据包,用来恳求关闭发送方到接纳方的衔接
  2. 接纳方发送一个应对,ACK标志位为1,确认关闭。此时完成了发起方到接纳方的衔接,也即发送方无法再向接纳方发送数据,但接纳方还能够向发送方发送数据。
  3. 接纳方数据传输完成后向发起方发送一个FIN为1的包,表示恳求断开衔接
  4. 发起方回复一个ACK包,确认关闭胜利
从TCP到Socket,彻底了解网络编程是怎样回事

图4 关闭衔接流程表示图

TCP是全双工通讯,因而关闭衔接时需求双向关闭衔接。首先是关闭发起方关闭本端的衔接,然后是关闭接纳方在收到发起方的关闭恳求后,除了回复关闭应对外,还要确保数据传输完成后发起一个关闭衔接的恳求,保证双向同时关闭。

更多精彩:

鲜花

握手

雷人

路过

鸡蛋

最新评论

阅芽精选PPT模板更多
Linux系统镜像更多
VR视频更多
Copyright   ©2017-2022  阅芽资讯