我在本科的时候比较系统学习过计算机网络,可惜好久不用了,所以,本篇文章是一个复习的笔记,我就挑一些我将来可能用到的东西去详细复习,所以像什么数据链路层和物理层我就不用去复习了(那部分是真的恶心)。

IP地址

区分局域网或互联网中的计算机设备。

  • 每一台电脑有一个 IP 地址。
  • 127.0.0.1为本地 localhost

程序测试:

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
26
27
import java.net.InetAddress;
import java.net.UnknownHostException;

public class Test {
public static void main(String[] args) {

try{

// 查询本地ip地址
// 可以使用以下方式查询:
// 1. 127.0.0.1
// 2. localhost
// 3. 直接使用.getLocalHost()方法
InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
System.out.println(inetAddress1);

// 查询百度ip地址
InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress2);

}
catch (UnknownHostException e){
e.printStackTrace();
}

}
}

除此之外还有一些方法可以直接去获取其他信息:

1
2
3
4
inetAddress1.getAddress();             // Byte 形式的地址(不常用)
inetAddress1.getCanonicalHostName(); // 规范的名字(不常用)
inetAddress1.getHostAddress(); // 获得 ip 地址
inetAddress1.getHostName(); // 获得域名(或者自己电脑名字)

端口

一台计算机上的一个进程。

  • 不同进程有不同端口号,主要用来区分软件。

  • 范围为 0~65535.

  • 端口号不能冲突。

  • 端口分类:

    • 公有端口(0~1023):

      | 服务协议 | 端口号 |
      | ———— | ——— |
      | HTTP | 80 |
      | HTTPS | 443 |
      | FTP | 21 |
      | Telent | 23 |

    • 程序注册端口(1024~49151):分配给用户

      | 程序 | 端口号 |
      | ——— | ——— |
      | Tomcat | 8080 |
      | MySQL | 3306 |
      | Oracle | 1521 |

    • 动态、私有端口(49152~65535):随机分配(尽量不去使用):

      • netstat -ano可以查看所有的端口
      • netstat -ano | findstr "6000"可以查看指定的端口
      • tasklist | findstr "6000"可以查看指定的端口的进程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.net.InetSocketAddress;

public class Test{

public static void main(String[] args) {

// 返回某个进程的端口号信息
InetSocketAddress socket = new InetSocketAddress("127.0.0.1",8080);
// 获取名字
System.out.println(socket.getHostName());
// 获取地址
System.out.println(socket.getAddress());
// 获取端口号
System.out.println(socket.getPort());

}
}

通信协议

  • TCP:用户传输协议
    • 连接、稳定
    • 三次握手,四次挥手
    • 明确服务端和客户端
    • 效率低
  • UDP:用户数据报协议
    • 不连接、不稳定
    • 服务端和客户端没有明显明确
    • 效率高
    • DDOS:洪水攻击(饱和攻击)

TCP

服务端程序

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

// 服务端
public class Server {
public static void main(String[] args) {

ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos= null;


try {
// 需要有一个地址,设置端口号为 9999
serverSocket = new ServerSocket(9999);

// 等待客户端连接
// 监听
socket= serverSocket.accept();

// 接收消息,实例化IO流
is = socket.getInputStream();

// 管道流
baos = new ByteArrayOutputStream();

byte[] buffer = new byte[1024];

int len;
while((len = is.read(buffer)) != -1){
baos.write(buffer,0,len);
}
System.out.println(baos.toString());



} catch (Exception e) {
e.printStackTrace();
}finally {
// 关闭流
if(baos != null){
try {baos.close();}
catch (IOException e) {e.printStackTrace();}

}
if(is != null){
try {is.close();}
catch (IOException e) {e.printStackTrace();}
}

if(socket != null){
// 关闭连接
try {socket.close();}
catch (Exception e) {e.printStackTrace();}
}

if(serverSocket != null){
// 关闭服务器
try {serverSocket.close();}
catch (IOException e) {e.printStackTrace();}
}
}
}
}

客户端程序

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

// 客户端
public class Client {
public static void main(String[] args) {
Socket socket = null;
OutputStream os = null;
try {
// 需要连接服务器的地址
InetAddress serverIP = InetAddress.getByName("127.0.0.1");

// 需要连接服务器的端口号
int port = 9999;

// 传入ip和端口,创建一个 socket 连接
socket = new Socket(serverIP, port);

// 发送消息,实例化IO流
os = socket.getOutputStream();

// 发送的内容
os.write("hello world".getBytes());


} catch (Exception e) {
e.printStackTrace();
}finally {

// 关闭流
if(os != null){
try {os.close();}
catch (IOException e) {e.printStackTrace();}
}

if(socket != null){
// 关闭连接
try {socket.close();}
catch (IOException e) {e.printStackTrace();}
}
}


}
}

UDP

服务端程序

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
26
27
28
29
30
31
32
33
34
35
36
37
38
package test;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

// 服务端
public class Test4 {
public static void main(String[] args) {

DatagramSocket socket = null;

try {

// 开放端口
socket = new DatagramSocket(9090);

// 接受数据包
byte[] buffer = new byte[1024];

// 先建一个包,用来接收
DatagramPacket pack = new DatagramPacket(buffer, 0,buffer.length);

socket.receive(pack);

System.out.println(new String(pack.getData()));

} catch (Exception e) {
e.printStackTrace();
}finally {
if(socket != null){
// 关闭连接
try {socket.close();}
catch (Exception e) {e.printStackTrace();}
}

}
}
}

客户端程序

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
26
27
28
29
30
31
32
33
34
35
36
package test;
import java.net.*;

// 客户端
public class Test5 {
public static void main(String[] args) {

try {
// 建立数据包连接
DatagramSocket socket = new DatagramSocket();

// 发送的ip地址
InetAddress serverIP= InetAddress.getByName("127.0.0.1");
// 发送的端口
int port = 9090;

// 新建一个包
// 参数是起始位置和结束位置
String massage = "hello word";
DatagramPacket pack = new DatagramPacket(
massage.getBytes(), //发送的数据
0, //起始位置
massage.getBytes().length, //结束位置
serverIP, // 接收ip
port // 端口号
);

// 发送包
socket.send(pack);

} catch (Exception e) {
e.printStackTrace();
}

}
}

URL

统一资源定位符

格式:

1
协议://ip地址:端口号/项目名/资源
1
URL url = new URL("http://localhost:8080");