From: 网络编程Tcp/Ip协议

概述

C/S:Client/Server 客户端/服务器(迅雷)

B/S:Browser/Server 浏览器/服务器(浏览器)

网络编程:在一定协议下,实现两台计算机的通信的程序

网络通信协议

  • 通过计算机网络可以使多台计算机连接,位于同一个网络中的计算机在进行连接和通信时需要遵守一定的规则,这些连接和通信遵守的规则叫做网络通信协议,对数据的传输格式,传输速率,传输步骤做了统一规定,双方必须同时遵守才能完成数据交换。(数据交换的规则约定的集合)

  • TCP/IP:传输控制协议/因特网互联协议,Internet最基本,最广泛的协议;使用4层模型。

四层模型

QQ截图20220820121630

物理层:硬件

数据链路层(网络接口):==相邻节点目标机==(网桥和交换机),网络传输数据组成数据块()的传输,以太网协议

网络层:==根据网络地址从源到目标节点==,即两个端系统的数据传输,路径选择,路由及逻辑寻址

IP协议 ICMP ARP PARP 路由器
因特互联 因特网控制报文 地址解析 逆地址解析 /
/ / 已知IP未知MAC 已知MAC未知IP /

传输层:==在目标节点将数据发送至对应端口==,端到端(主机到主机)传输传输的协议数据单元为报文

TCP UDP 网关
传输控制 用户数据报 /

应用层(软件):为系统或网络应用程序提供网络服务接口

FTP Telent DNS SMTP Pop3 Http
文件传输 远程登录 域名解析 邮件传送 邮局 超文本传输协议

DNS:域名解析,URL地址转为IP地址,域名与IP地址一一对应

https 比 http安全

协议分类

  • UDP

    用户数据报协议,面向无连接通信协议,数据的发送端和接收端不建立逻辑连接

    eg:两台主机,主机1给主机2发送数据,主机1不会确认主机2是否存在,主机2不会反馈是否接受到主机1的数据

    应用:由于协议消耗资源少,通信效率高,常用语音频、视频等普通数据的传输。UDP协议由于面向无连接性,不能保证数据稳定性,会存在丢包的情况。例如视频会议,广播,QQ聊天功能,查询-应答

  • TCP

    传输控制协议,面向连接的通信协议,即传输数据之前,在发送端和接受端建立逻辑连接,然后再传输数据。明确客户端和服务器,每次创建连接都需要经历“三次握手”。

    QQ截图20220820122728

TCP三次握手详解

From: https://blog.csdn.net/qq_40337086/article/details/112443124

  1. 初始状态
    服务端监听某个端口,处于 LISTEN 状态。

  2. 客户端发送TCP连接请求
    客户端会随机一个初始序列号seq=x(client_isn)
    设置SYN=1 ,表示这是SYN握手报文。然后就可以把这个 SYN 报文发送给服务端了,表示向服务端发起连接,之后客户端处于 同步已发送 状态。

  3. 服务端发送针对TCP连接请求的确认
    服务端收到客户端的 SYN 报文后,也随机一个初始序列号seq=y(server_isn)
    设置ack=x+1, 表示收到了客户端的x之前的数据,希望客户端下次发送的数据从x+1开始。
    设置 SYN=1ACK=1。表示这是一个SYN握手和ACK确认应答报文。
    最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于同步已接收状态。

  4. 客户端发送确认的确认
    客户端收到服务端报文后,还要向服务端回应最后一个应答报文,
    设置ACK=1 ,表示这是一个应答报文
    ack=y+1 ,表示收到了服务器的y之前的数据,希望服务器下次发送的数据从y+1开始。
    最后把报文发送给服务端,这次报文可以携带数据,之后客户端处于 连接已建立 状态。
    服务器收到客户端的应答报文后,也进入连接已建立状态

20210110193713551

TCP报文格式

QQ截图20220821120055

编程三要素

协议

IP地址

  • 互联网协议地址,用于给一个网络中的计算机设备做唯一编号

IP地址分类

  • IPv4

    32位,4字节, 表示为a, b, c, d,例如192,168,65,100,每个值为 0~255 之间的十进制整数

    • 自动获得
    • 手动输入
  • IPv6

    128位,16字节一组,,分成8组16进制,表示为ABCD: EF01: 2345:6789:ABCD: EF01: 2345: 678

子网掩码

  • 标志两个IP属于同一个子网

常用命令

  • 本机IP地址
1
ipconfig
  • 检查网络是否连通
1
2
ping 空格 IP地址
ping 172.16.184.173
  • 特殊IP地址

    本机:127.0.0.1localhost

端口号

所以开VPN的时候因为占用了同样的端口,两个软件会打架,导致连不上网

QQ截图20220820144944


TCP 通信程序

连接步骤

先区分客户端(Client)和服务端(Server)

步骤

  1. 服务端程序事先启动,等待客户端连接
  2. 客户端主动连接服务器,连接成功才能通信,服务端不可以主动连接客户端
  3. 客户端向服务端发送IO流对象,IO流对象在客户端的Socket对象中
  4. 服务端没有IO流,读取Socket对象s1中的IO流对象数据
  5. 服务端通过s1中的IO流对象发送数据给客户端确认收到
  6. 客户端读取服务端确认收到的数据

QQ截图20220820150706

Socket 类

客户端

TCP通信的客户端:向服务器发送连接请求,给服务器发送数据,读取服务器回写的数据
表示客户端的类
java.net.Socket:此类实现客户端套接字,套接字是两台机器间通信的端点
套接字:包含了IP地址和端口号的网络单位
构造方法
Socket(String host, int port) 创建一个套接字并将其连接到指定主机的指定端口号(找到对应服务器)
参数
string host:服务器主机名称/服务器IP地址
int port:服务器端口号
成员方法
OutputStream getOutputStream() 返回此套接字的输出流
InputStream getInputStream() 返回此套接字的输入流
void close() 关闭此套接字
实现步骤

  1. 创建一个客户端对象socket,构造方法绑定服务器的IP地址和端口号

  2. 使用Scoket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象

  3. 使用网络字节输出流OutputStream对象中的方法write,给服务器发送数据

  4. 使用Scoket对象中的方法getOutputStream()获取网络字节输入流InputStream对象

  5. 使用网络字节输入流InputStream对象中的方法read,读取服务器回写的数据

  6. 释放资源(Socket)

    注意

    1. 客户端和服务器端进行交互必须使用Socket中提供的网络流,不能使用自己创建的刘对象

    2. 当我们创建客户端对象Socket的时候,就回去请求服务器和服务器经过三次握手建立连接通路
      这时如果服务器没有启动,那么就会抛出异常
      如果服务器已经启动,那么久可以进行交互

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 客户端
public class TCPClient
{
// 主方法
public static void main(String[] args) throws IOException
{
// 1. 创建一个客户端对象socket,构造方法绑定服务器的IP地址和端口号
Socket socket = new Socket("127.0.0.1", 8888);

// 2. 使用Scoket对象中国的方法getOutputStream()获取网络字节输出流OutputStream对象
OutputStream os = socket.getOutputStream();
// 3. 使用网络字节输出流OutputStream对象中的方法write,给服务器发送数据
os.write("你好服务器".getBytes());
// 4. 使用Scoket对象中的方法getOutputStream()获取网络字节输入流InputStream对象
InputStream is = socket.getInputStream();
// 5. 使用网络字节输入流InputStream对象中的方法read,读取服务器回写的数据
byte[] bytes = new byte[1024];
int len = is.read(bytes);
System.out.println(new String(bytes, 0,len));

// 6. 释放资源(Socket)
socket.close();
}
}

服务端

TCP通信的服务器端:接受客户端的请求,读取客户端发送的数据,给客户端回写数据
表示服务器的类
java.net.ServerSocket:此类实现服务端套接字
构造方法
ServerSocket(int port) 创建绑定到特定端口的服务器套接字
服务器必须明确一件事情,必须知道是哪个客户端请求的服务器
所以可以使用accept方法获取到请求的客户端对象Socket
成员方法
Socket accecpt() 倾听并接受此套接字的连接(获取客户端套接字)
服务器的实现步骤

  1. 创建服务器ServerSocket对象和系统要指定的端口号
  2. 使用ServerSocket对象中的方法accept,获取请求的客户端对象socket
  3. 使用Scoket对象中的方法getInputStream()获取网络字节输入流InputStream对象
  4. 使用网络字节输出流InputStream对象中的方法read,读取客户端发送的数据
  5. 使用Scoket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象
  6. 使用网络字节输出流OutputStream对象中的方法write,给客户端回写数据
  7. 释放资源(Socket,SeverSocket)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 服务器
public class TCPServer
{
public static void main(String[] args) throws IOException{
// 1. 创建服务器ServerSocket对象和系统要指定的端口号
ServerSocket server = new ServerSocket(8888);
// 2. 使用ServerSocket对象中的方法accept,获取请求的客户端对象socket
Socket socket = server.accept();

// 3. 使用Scoket对象中的方法getInputStream()获取网络字节输入流InputStream对象
InputStream is = socket.getInputStream();
// 4. 使用网络字节输出流InputStream对象中的方法read,读取客户端发送的数据
byte[] bytes = new byte[1024];
int len = is.read(bytes);
System.out.println(new String(bytes, 0,len));
// 5. 使用Scoket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象
OutputStream os = socket.getOutputStream();
// 6. 使用网络字节输出流OutputStream对象中的方法write,给客户端回写数据
os.write("收到谢谢".getBytes());

// 7. 释放资源(Socket,SeverSocket)
socket.close();
server.close();
}
}

文件上传实例

QQ截图20220820201253


访问浏览器实例

QQ截图20220821172724