网络编程
javaweb:网页编程 B/S
网络编程:TCP/IP C/S
要解决的问题
-
如何准确地定位到网络地一台或者多台主机
-
找到主机之后如何通信
IP地址:
Java中使用InetAddres表示IP地址
-
唯一定位一台网络上计算机
-
127.0.0.1:本机localhost
-
ip地址的分类:
- IPv4/IPv6
- IPv4:四个字节组成,0~255,42亿,30亿都在北美,亚洲4亿,2011年就用尽了
- IPv6:
- 公网(互联网)-私网(局域网):
- 192.168.xx.xx,专门给组织内部使用
- ABCD类地址
- IPv4/IPv6
-
域名:记忆IP问题
端口
单个协议下,端口号不能冲突,不同协议下,端口号可以重名
端口分类:
-
公有端口0~1023
- HTTP:80
- HTTPS:443
- FTP:21
- Telent:23
-
程序注册端口:1024~49151,分配用户或者程序
- Tomcat:8080
- MySQL:3306
- Qracle:1521
TCP
服务器
- 建立服务的端口 SeverSocket
- 等待用户的连接 accept
- 接收消息
客户端
- 连接服务器Socket
- 发送消息
实现客服端向服务器传输文件和发送信息
服务端
package net;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer02 {
public static void main(String[] args) throws Exception {
// 创建服务
ServerSocket serverSocket = new ServerSocket(9090);
// 监听客户端的连接
Socket socket = serverSocket.accept(); // 此处阻塞,直到获得连接
// 获取输入流
InputStream is = socket.getInputStream();
// 文件输出到本地
FileOutputStream fos = new FileOutputStream("345.txt");
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1){
fos.write(buffer, 0, len);
}
// 获取输出流,给客户端发送信息
OutputStream os = socket.getOutputStream();
os.write("我接受完了,你可以断开了".getBytes());
// 关闭资源
os.close();
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
客户端
package net;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class TcpClient02 {
public static void main(String[] args) throws Exception {
// 创建一个Socket连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
// 创建一个输出流
OutputStream os = socket.getOutputStream();
// 流读取文件
FileInputStream fis = new FileInputStream("./123.txt");
byte[] buffer = new byte[1024];
int len;
while((len=fis.read(buffer)) != -1){
// 输出给客户端
os.write(buffer);
}
// 输出完毕
socket.shutdownOutput();
// 读取服务器的读入
InputStream inputStream = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((len=inputStream.read(buffer)) != -1){
baos.write(buffer, 0, len);
}
System.out.println(baos.toString());
关闭资源
baos.close();
inputStream.close();
os.close();
fis.close();
socket.close();
}
}
上述没有捕获异常,选择抛出,从而简化代码。实际中一定要捕获异常。
UDP
使用多线程做一个聊天器
发送器
package net.chat;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.Scanner;
public class UdpSendDemo implements Runnable{
String toIP;
int toPort;
Scanner scanner = new Scanner(System.in);
DatagramSocket socket;
DatagramPacket packet;
public UdpSendDemo( String toIP, int toPort){
this.toIP = toIP;
this.toPort = toPort;
}
@Override
public void run() {
try{
this.socket = new DatagramSocket();
while (true){
// 从控制台获取信息,并转换成byte[]数组
String msg = scanner.nextLine();
byte[] data = msg.getBytes();
// 打包成数据包,格式为:数据+起止位置+对方IP和端口号
packet = new DatagramPacket(data, 0,
data.length, new InetSocketAddress(toIP, toPort));
// 发送
socket.send(packet);
}
}catch (Exception e){
e.printStackTrace();
}
socket.close();
}
}
接收器
package net.chat;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UdpReceiveDemo implements Runnable{
int port;
String personName;
DatagramSocket socket;
DatagramPacket packet;
public UdpReceiveDemo(int port, String personName){
this.port = port; // 接收的端口号
this.personName = personName; // 用户名,表示谁发来的
}
@Override
public void run() {
try{
// 用接收端口号实例化一个DatagramSocket对象
socket = new DatagramSocket(port);
while (true){
// 接收数据的容器
byte[] buffer = new byte[1024];
packet = new DatagramPacket(buffer, 0, buffer.length);
socket.receive(packet); // 此处为阻塞接收
byte[] data = packet.getData();
String msg = new String(data, 0, data.length);
System.out.println(personName + ":" + msg);
}
}catch (Exception e){
e.printStackTrace();
}
socket.close();
}
}
调用
public class Student {
public static void main(String[] args) {
new Thread(new UdpSendDemo("127.0.0.1", 9999)).start();
new Thread(new UdpReceiveDemo(4444, "老师")).start();
}
}
public class Teacher {
public static void main(String[] args) {
new Thread(new UdpSendDemo("127.0.0.1", 4444)).start();
new Thread(new UdpReceiveDemo(9999, "学生")).start();
}
}
初识Tomcat
服务端
- 自定义服务器 S
- Tomcat服务器 S
客户端
- 自定义 C
- 浏览器 B
URL
通过url下载资源到本地
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class TestUrldownload {
public static void main(String[] args) throws Exception {
String addr = "https://m801.music.126.net/20201125121536/ea12b3f4a885b2e83e66480c9f952a06/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/4903215562/5bfc/fbd2/fa38/adfd6bf3d0fb529fb2681943d6065842.m4a";
URL url = new URL(addr); // new一个URL对象
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 打开连接
InputStream is = connection.getInputStream(); // 获得输入流
byte[] buffer = new byte[1024];
FileOutputStream fos = new FileOutputStream("是但求其爱.m4a"); // 输出到本地
int len;
while ((len=is.read(buffer)) != -1){
fos.write(buffer, 0, len);
}
//关闭资源
fos.close();
is.close();
connection.disconnect();
}
}