局域网(loacal network LAN):被路由器网线直接连接起来的设备 (国家)
广域网(Wide Area Networj WAN):局域网组合形成广域网 (世界)
针对LAN,主机是可以直接通信的
组网:
1.主机-主机
2.星形、总线、环形...
网络设备的存在:集线器hub 、交换机switch
集线器:类似插座,消息中携带目标信息,只有目标主机接受数据,其他主机直接忽略
职责:交给数据链路层
数据链路层:解决一个局域网内部的数据通信
冲突域:冲突避免
交换机switch:
交换机是可以知道数据发送给哪个目标的,只会把数据交给对应的主机
交换机在数据链路层工作
网络层:跨局域网的主机之间通信的问题
路由器roter在网络层工作
传输层:解决进程 对 进程通信的问题
应用层:在解决了通信问题的情况下,各个业务具体是怎么通信的
MAC地址:
物理地址:绑定在网卡上的一个地址(硬件地址),MAC地址是“绝对唯一的”
数据链路层使用
IP地址:
在网络层使用
一个网络内部的IP地址,不应该重复(软件地址)
IPV4: 0-255 . 0-255 . 0-255. 0 - 255
端口port:
在一个主机内部用来区分不同进程的0 -65525
我们依赖ip+port :可以唯一确定网络中的一个进程
通过Ip地址,一定可以唯一的确定网络中的一台主机
通过端口,一定可以唯一的确定主机内部的一个进程
通信主体A: ip1:port1
通信主体B:ip2:port2
一般称这组信息为四元组信息
四元组:唯一确定网络中的一条通信“线路”
发送ip:发送port+目标ip:目标port
本地ip: 本地port +远端ip :远端port
传输层:TCP/UDP
五元组:协议:ip1:port :ip2 :port2
进程和端口的关系:一个进程可以同时绑定多个端口,一个端口同一时刻,只能属于一个进程
封装:
数据链路层:发送数据帧frame
网络层:发送数据包facket
传输层:
UDP:报文 datagram
TCP:段 segment
TCP:面向字节流 让A送信,A一天只送一次,可能堆积数据一起发送
发送[abc] [def] [ghi] -> 收到 [abcde] [fghi]
UDP:面向数据报文 让A送信,给A之后,A立即去送
发送 [abc] -> 收到[abc]
应用层:
请求-响应模型、订阅-推送模型
HTTP:请求request、相应response、
网络的分布式架构造成以下特点:
1.数据在整个通信线路上对于线路中的设备实际是透明的(存在数据监听和数据篡改的风险)
2.网络在发送中天生是不可靠的(不保证数据一定能发送给对方)
3.来回的线路并不一致
时序上:服务器先启动,bind一个端口(有可能出现错误)port: 8080
1.本机的进程间通信via网络,是不会经过网卡设备的
2.所有的代码都是应用层代码,使用了传输层UDP协议(UDP会使用IP进而使用数据链路层)
3.服务器提前启动,绑定在某个端口上
客户随后指定IP+PORT,进行数据的发送
请求的五元组:UDP+源IP:127.0.0.1+源port:9999 +目标ip:120.0.0.1+目标port:8080
4.请求-响应模型
TCP/IP五层
层次 | 主要职责 | 重点协议 | 主要设备 | 相关概念 |
应用层 | 处理业务逻辑 | HTTP(S)、DNS | 请求、响应 | |
传输层 | 跨主机,进程到进程 | TCP、UDP | 段、报文、端口 | |
网络层 | 跨LAN,主机到主机 | IP | 路由器 | 包/IP地址 |
数据链路层 | LAN内,主机到主机 | 交换机 | 帧/MAC地址 | |
物理层 | 通信介质上的传输 | 集线器 |
观察数据封装的过程:
1.OS的代码进行封装
2.观察封装后的数据(抓包工具——wireshark)
网络编程的业务模型:
1.写死请求
2.由用户输入,完成翻译
3.变成一个命令行程序
如何解决端口被占用问题?
如果是BindException:Address already in use:JVM Bind
创建地址失败,地址已经被使用,说明该端口(TCP:8080)已经被其他进程占用了
解决办法有两个:
1.找到哪个进程占用了这个端口,判断这个进程是否惹得起,如果是不重要的进程,就把对应的进程先关掉,把端口腾出来
2.重新换个端口试试
那么如何找到哪个进程占用了了端口呢?
windows上:1,通过一个命令行程序cmd
2,输入netstat -nao | findstr 8080
进程(pid == 51340)占用了(监听: listen)tcp:8080 端口
根据pid,看进程的具体信息 via 任务管理器
找到了:
TCP: 长连接 vs 短连接
长连接:拨通电话 -> 请求 ->响应 ->请求 -> 响应 -> 请求 ->... ->挂断电话
再进行应用层协议设计时,需要考虑:请求中需要有明确的分界线,帮助服务器划分不同的请求
具体方法:
1.采用定长的方式:比如:请求的固定长度是10个字节
2.采用变长的方式:
1.先发送长度+真正的请求 [18+...]
2.使用特殊的字符区分不同的请求:
比如读到两次\r\n就代表一个请求
短连接:拨通电话 -> 请求 ->响应 ->挂断电话 ->拨通电话 ->请求 ->响应 ->挂断电话....