网络基础

什么是ip地址?

IP(Internet Protocol Address)地址是指互联网协议地址,又叫网际协议地址,IP地址是IP协议提供的一种统一的地址格式,他为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。

IP地址是一个32位的二进制数,通常被分割为4个 '8位二进制数'(也就是4个字节)。IP地址通常用“点分十进制”表示成(a,b,c,d)的形式,其中,a,b,c,d都是0~255之间的十进制整数。

例:点分十进制IP地址(100.4.5.6),实际上是32位二进制数(01100100.00000100.00000101.00000110)

什么是端口?

“端口”是英文port的意译,可以认为是设备与外界通讯交流的出口。

  端口的概念是虚拟的。

  端口的范围:0~65535。

  在同一台机器上,同一时刻,每个端口只能为一个运行中的程序提供服务。

  只有用到联网通信的程序才会用到端口概念。

  我们网络访问必须经过的一条路——端口。

IP地址精确到具体的一台电脑,而端口精确到具体的程序。

  所以使用ip+端口:就可以找到全世界唯一的一台电脑上的一个程序。

arp协议——查询IP地址和MAC地址的对应关系。

  地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。

  主机发送信息时将包含目标的IP地址的ARP请求广播到网络上的所有主机,并接受返回消息,以此确定目标的物理地址。

  收到返回消息后将该IP地址和物理地址存入本机APR缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。

  地址解析协议是建立在网络中各个主机互相信任的基础上的,网络的主机可以自主发送ARP应答消息,其他主机收到应答报文时不会检测该报文的真实性就会将其记入本机ARP缓存;由此攻击者就可以向某一主机发送伪ARP应答报文,使其发送的信息无法达到预期的主机或到达错误的主机,这就构成了一个ARP欺骗。ARP命令可用于查询本机ARP缓存中的IP地址和MAC地址的对应关系,添加或删除静态对应关系等。相关协议又RARP,代理ARP。NDP用于IPv6中,代替地址解析协议。

tcp协议:可靠的,面向连接,全双工的链接。

  当应用程序希望通过 TCP 与另一个应用程序通信时,它会发送一个通信请求。这个请求必须被送到一个确切的地址。在双方“握手”后,TCP 将在两个应用程序之间建立一个全双工(full-duplex)的通信。

  这个全双工的通信将占用两个计算机之间的通信路线,直到它被一方或双方关闭为止。

TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答SYN+ACK[1],并最终对对方的 SYN 执行 ACK 确认。这种建立连接的方法可以防止产生错误的链接。


TCP三次握手的过程如下:
1,客户端发送SYN(SEQ=x)报文给服务器端,进入SYN_SEND状态。
2,服务器端收到SYN报文,回应一个SYN(SEQ=y)ACK(ACK=x+1)报文,进入SYN_RECV状态。
3,客户端收到服务器端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态。

三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了。
TCP的三次握手
建立一个链接需要三次握手,而终止一个链接需要经过四次挥手,这是由TCP的半关闭(half-close)造成的。
1,某个应用进程首先调用close,称该端执行“主动关闭”(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。
2,接收到这个FIN的对端执行“被动关闭”(passive close),这个FIN由TCP确认。
    注意:FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。
3,一段时间后,接收到这个文件结束符的应用进程将调用close关闭他的套接字,这导致它的TCP也发送一个FIN。
4,接受这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。
既然每个方向都需要一个FIN和一个ACK,因此通常需要4个字节。

注意:
1,“通常”是指,某些情况下,步骤1的FIN随数据一起发送,另外,步骤2和步骤3发送的分节都出自执行被动关闭的那一端,有可能被合并成一个分节。
2,在步骤2与步骤3之间,从执行被动关闭一端到执行主动关闭一端流动数据是可能的,这称为“半关闭”(half-close).
3,当一个Unix进程无论自愿地(调用exit或从main函数返回)还是非自愿地(收到一个终止本进程的信号)终止时,所有打开的描述符都被关闭,这也导致仍然打开的任何TCP连接上也发出一个FIN。

无论是客户还是服务器,任何一端都可以执行主动关闭。通常情况是,客户执行主动关闭,但是某些协议,例如:HTTP/1.0却由服务器执行主动关闭。
TCP的四次挥手

udp协议:不可靠的,面向数据包的,传输速度快,且不会长期占用系统的连接资源。

  当应用程序希望通过UDP与一个应用程序通信时,传输数据之前源端和终端不建立链接。

  当它想传送时就简单的去抓取来自应用程序的数据,并尽可能快的把它扔到网络上。

tcp 和 udp 的对比:

  TCP--传输控制协议,提供的是面向连接,可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP链接,之后才能传输数据,TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证能从一端传到另一端。

  UDP--用户数据包协议,是一个简单的面向数据包的运输协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据包发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据包前不用在客户端和服务器端建立一个链接且没有超市重发机制,故而传输速度很快。

现在Internet上流行的协议是TCP/IP协议,该协议中对低于1024的端口都有确切的定义,他们对应着Internet上一些常见的服务。这些常见的服务可以分为使用TCP端口(面向连接)和使用UDP端口(面向无连接)两种。 
说到TCP和UDP,首先要明白“连接”和“无连接”的含义,他们的关系可以用一个形象地比喻来说明,就是打电话和写信。两个人如果要通话,首先要建立连接——即打电话时的拨号,等待响应后——即接听电话后,才能相互传递信息,最后还要断开连接——即挂电话。写信就比较简单了,填写好收信人的地址后将信投入邮筒,收信人就可以收到了。从这个分析可以看出,建立连接可以在需要痛心地双方建立一个传递信息的通道,在发送方发送请求连接信息接收方响应后,由于是在接受方响应后才开始传递信息,而且是在一个通道中传送,因此接受方能比较完整地收到发送方发出的信息,即信息传递的可靠性比较高。但也正因为需要建立连接,使资源开销加大(在建立连接前必须等待接受方响应,传输信息过程中必须确认信息是否传到及断开连接时发出相应的信号等),独占一个通道,在断开连接钱不能建立另一个连接,即两人在通话过程中第三方不能打入电话。而无连接是一开始就发送信息(严格说来,这是没有开始、结束的),只是一次性的传递,是先不需要接受方的响应,因而在一定程度上也无法保证信息传递的可靠性了,就像写信一样,我们只是将信寄出去,却不能保证收信人一定可以收到。 
TCP是面向连接的,有比较高的可靠性, 一些要求比较高的服务一般使用这个协议,如FTP、Telnet、SMTP、HTTP、POP3等。
而UDP是面向无连接的,使用这个协议的常见服务有DNS、SNMP、QQ等。对于QQ必须另外说明一下,QQ2003以前是只使用UDP协议的,其服务器使用8000端口,侦听是否有信息传来,客户端使用4000端口,向外发送信息(这也就不难理解在一般的显IP的QQ版本中显示好友的IP地址信息中端口常为4000或其后续端口的原因了),即QQ程序既接受服务又提供服务,在以后的QQ版本中也支持使用TCP协议了。
tcp和udp的更多区别

互联网协议与OSI模型:

  互联网协议按照功能不同分为osi七层或tcp/ip五层或tcp/ip四层

每层运行常见的物理设备:

每层运行常见的协议:

socket概念:

  socket是应用层与TCP/IP协议组通信的中间软件抽象层,它是一组接口,在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Scoket去组织数据,以符合指定的协议。

  socket层:

其实站在你的角度上看,socket就是一个模块。我们通过调用模块中已经实现的方法建立两个进程之间的连接和通信。
也有人将socket说成ip+port,因为ip是用来标识互联网中的一台主机的位置,而port是用来标识这台机器上的一个应用程序。
所以我们只要确立了ip和port就能找到一个应用程序,并且使用socket模块来与之通信。
站在自己的角度上看socket

套接字(socket)初使用:

  基于TCP协议的socket:

    tcp是基于链接的,必须先启动服务端,然后再启动客户端去连接服务端。

import socket

sk = socket.socket()

sk.bind(('127.0.0.1',8000))

sk.listen()

conn,addr = sk.accept()

ret = conn.recv(1024)

print(ret.decode('utf-8'))

conn.send(b'hi')

conn.close()

sk.close()
Server
import socket

sk = socket.socket()

sk.connect(('127.0.0.1',8000))

sk.send('你好'.encode('utf-8'))

ret = sk.recv(1024)

print(ret.decode('utf-8'))

sk.close()
Client
原文地址:https://www.cnblogs.com/stfei/p/8986374.html