网络编程
1. 概述
计算机网络
计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
待解决的问题
- 如何定位网络上的一台主机上的某个资源?
- 如何进行数据传输?
2. 网络通信的要素
通信双方地址
- IP地址:唯一定位网络上的一台主机
- 端口号:定位主机上的一个进程
网络通信协议
3. IP
查看IP地址的命令
Windows:ipconfig
MAC:ifconfig en0
IP地址 InetAddress
-
127.0.0.1/localhost:本机
-
IP地址分类
-
公网(互联网)/ 私网(局域网)
-
IPV4/IPV6
-
IPV4 32位,0-255,42亿;30亿在北美,亚洲4亿,2011年用尽
127.0.0.1
-
IPV6 128位,8个无符号整数
2001:0ab2:12d2:0000:ac34:1245:1aaa:0000
-
-
public class IpDemo {
public static void main(String[] args) {
try {
// 查询本机IP地址
System.out.println(InetAddress.getByName("127.0.0.1"));
System.out.println(InetAddress.getByName("localhost"));
System.out.println(InetAddress.getLocalHost());
// 查询网站IP地址
System.out.println(InetAddress.getByName("www.baidu.com"));
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
4. 端口
端口 InetSocketAddress
-
不同进程有不同的端口号
-
范围 0~65535
-
TCP + UDP 共 2 * 65535 个端口号,确保单个协议下端口号不冲突
-
端口分类
-
公有端口 0~1023
- HTTP:80
- HTTPS:443
- FTP:21
- SSH:22
- Telnet:23
-
程序注册端口号 1024~49151
-
Tomcat:8080
-
MySQL:3306
-
Oracle:1521
-
-
动态私有端口 49152~6 5535
-
查看端口命令
# Windows
netstat -ano # 查看所有端口
netstat -ano|findstr “5900” # 查看指定的端口
tasklist|findstr “8696” # 查看指定端口的进程
public class TestPort {
public static void main(String[] args) {
InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);
System.out.println(socketAddress.getHostName());
System.out.println(socketAddress.getPort());
System.out.println(socketAddress.getAddress());
}
}
5. 通信协议
TCP/IP协议簇
- TCP:传输控制协议
- UDP:用户数据报协议
- IP:网络互连协议
TCP和UDP的对比
6. TCP
发送消息Demo
客户端
- 利用Socket连接服务器
- 发送消息
public class TcpClient {
public static void main(String[] args) {
Socket socket = null;
OutputStream os = null;
try{
// 获取服务器地址,端口号
InetAddress address = InetAddress.getLocalHost();
int port = 9999;
// 创建socket连接
socket = new Socket(address, port);
// 发送消息IO流
os = socket.getOutputStream();
os.write("Hello World".getBytes());
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
服务端
- 利用ServerSocket建立服务端口
- 等待用户连接 accept
- 接受消息
public class TcpServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
// 利用ServerSocket建立服务端口
serverSocket = new ServerSocket(9999);
// 等待客户端连接
socket = serverSocket.accept();
// 读取客户端消息
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 (IOException e) {
e.printStackTrace();
} finally {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文件上传Demo
客户端
public class TcpClient {
public static void main(String[] args) throws Exception {
// 获取服务器地址,端口号
InetAddress ip = InetAddress.getByName("127.0.0.1");
int port = 9000;
// 创建socket连接
Socket socket = new Socket(ip, port);
// 创建输出流
OutputStream os = socket.getOutputStream();
// 读取文件
FileInputStream fis = new FileInputStream(new File("send.png"));
// 写出文件
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
// 关闭资源
fis.close();
os.close();
socket.close();
}
}
服务端
public class TcpServer {
public static void main(String[] args) throws Exception {
// 创建服务
ServerSocket serverSocket = new ServerSocket(9000);
// 监听客户端连接
Socket socket = serverSocket.accept();
// 获得输入流
InputStream is = socket.getInputStream();
// 文件输出
FileOutputStream fos = new FileOutputStream(new File("receive.png"));
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
// 关闭资源
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
C/S和B/S
客户端
- 自定义 C
- 浏览器 B
服务端
- 自定义 S
- Tomcat服务器 S
7. UDP
发送方
public class UdpClient {
public static void main(String[] args) throws Exception{
// 建立一个socket
DatagramSocket socket = new DatagramSocket();
// 建立一个数据包
String message = "Hello World!";
InetAddress ip = InetAddress.getByName("localhost");
int port = 9000;
DatagramPacket packet = new DatagramPacket(message.getBytes(), 0, message.getBytes().length, ip, port);
//发送数据包
socket.send(packet);
// 关闭连接
socket.close();
}
}
接收方
public class UdpServer {
public static void main(String[] args) throws Exception{
// 开放端口
DatagramSocket socket = new DatagramSocket(9000);
// 接收数据包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
// 阻塞接收
socket.receive(packet);
System.out.println(new String(packet.getData(), 0, packet.getLength()));
// 关闭连接
socket.close();
}
}