IP
inetAddress类,此类表示Internet协议(IP)地址
IP是用来定位节点/电脑的
InetAddress类常用方法
返回值类型 | 方法名 | 解释 |
---|---|---|
InetAddress | getLocalHost() | 静态方法,返回本机的InetAddress对象 |
String | getHostAddress() | 返回IP地址 |
String | getHostName() | 返回计算机名 |
InetAddress | getByName() | 给定主机名,返回主机的InetAddress对象,主机名可以是www地址,或者是ip地址 |
示例代码
public class demo01 {
public static void main(String[] args) throws UnknownHostException {
//获取本地主机InetAddress对象
InetAddress inetAddress = InetAddress.getLocalHost();
//打印主机地址和主机名
System.out.println("本机IP:"+inetAddress.getHostAddress());
System.out.println("本机名:"+inetAddress.getHostName());
//通过主机名获取主机InetAddress对象
inetAddress = InetAddress.getByName("www.qkmango.top");
System.out.println("主机IP:"+inetAddress.getHostAddress());
System.out.println("主机名:"+inetAddress.getHostName());
}
}
端口
端口是区分软件的 ,区分计算机中不同的进程
了解端口
InetSocketAddress类常用方法
返回值类型 | 方法名 | 解释 |
---|---|---|
InetSocketAddress | InetSocketAddress(“网址/IP地址”,端口) | 构造方法 |
inetAddress | getAddress() | 返回inetAddress类对象 |
String | getHostName() | 返回主机名 |
int | getPort() | 返回主机端口号 |
URL
了解URL
URL是互联网三大基石之一:html、http、url
- URI = Universal Resource Identifier 统一资源标志符,用来标识抽象或物理资源的一个紧凑字符串。
- URL = Universal Resource Locator 统一资源定位符,一种定位资源的主要访问机制的字符串,一个标准的URL必须包括:protocol、host、port、path、parameter、anchor。
- URN = Universal Resource Name 统一资源名称,通过特定命名空间中的唯一名称或ID来标识资源。
在www上,每个资源都有一个统一且唯一的地址,即统一资源定位符URL,
如:http://www.baidu.com:80/index.html?name=mango&age=19#a
协议 主机名 端口 资源路径 参数列表
- 协议 http
- 主机名 www.baidu.com
- 端口号 80
- 资源路径 index.html
- 参数列表
常用方法
返回值类型 | 方法名 | 解释 |
---|---|---|
String | getProtocol() | 获取协议 |
String | getHost() | 获取主机名(域名、IP) |
int | getPort() | 获取端口号 |
String | getFile() | 请求资源,获取资源文件名,有路径,包括参数 |
String | getPath() | 请求资源,获取资源文件路径,无参数 |
String | getQuery() | 获取参数,获取此URL的查询名 |
String | getRef() | 获取锚点 |
示例
public class demo01 {
public static void main(String[] args) throws MalformedURLException {
//创建一个URL
URL url = new URL("http://www.baidu.com:80/index.html?name=mango&age=19#a");
System.out.println("协议"+url.getProtocol());
System.out.println("域名/IP"+url.getHost());
System.out.println("端口号"+url.getPort());
System.out.println("请求资源"+url.getFile()); //获取资源文件名,包括参数
System.out.println("请求资源"+url.getPath()); //获取资源文件名
System.out.println("参数"+url.getQuery()); //获取此URL的查询部分
System.out.println("锚点"+url.getRef()); //获取锚点
}
}
TCP编程
TCP的优点
可靠,稳定 TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。 TCP的缺点: 慢,效率低,占用系统资源高,易被攻击 TCP在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源。
Socket类
socket即套接字,由IP/www和端口号构成的
常用构造方法
Socket(String host, int port)
传入主机地址和端口号
常用重要方法
返回值类型 | 方法 | 说明 |
---|---|---|
InputStream | getInputStream() | 返回此套接字的输入流 |
OutputStream | getOutputStream() | 返回此套接字的输出流 |
void | close() | 关闭此套接字 |
void | shutdownOutput() | 禁用此套接字的输出流 |
void | shutdownInput() | 禁用此套接字的输入流 |
当然还有其他的基本方法,如获取端口号等等,不一一列举
ServerSocket类
服务器端套接字,这个类实现了服务器套接字。 服务器套接字等待通过网络进入的请求
常用构造方法
ServerSocket(int port)
指定端口创建服务端套接字对象
常用方法
返回值类型 | 方法 | 说明 |
---|---|---|
Socket | accept() | 获取客户端套接字,侦听要连接到此套接字并接受它 |
void | close() | 关闭此套接字 |
客户端向服务端发送一个请求,服务端通过accept()接收取出请求,获得一个socket对象,服务端可客户端通过操作socket的输入输出流进行通信,客户端向服务端通过socket发送数据,发送完毕后,服务端要返回客户端数据的话,客户端要主动关闭socket的输出流,不然服务端会一直监听接收来自客户端的数据
- TCP网络编程:客户端发送信息给服务端,并打印出来
public class demo01 {
public static void main(String[] args) {
new Thread(new SocketThread()).start();
new Thread(new ServerSocketThread()).start();
}
}
class SocketThread implements Runnable {
@Override
public void run() {
//创建客户端套接字对象,指定服务端的IP和端口
try(Socket socket = new Socket("127.0.0.1",3307);
//通过客户端套接字获取输出流
OutputStream os = socket.getOutputStream();
BufferedReader isr = new BufferedReader(new InputStreamReader(System.in))) {
while (true) {
String msg = isr.readLine();
//通过输出流写出信息
os.write(msg.getBytes());
if(msg.equals("exit")) {
break;
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ServerSocketThread implements Runnable {
@Override
public void run() {
//服务端指定端口,创建服务端套接字对象
try(ServerSocket serverSocket = new ServerSocket(3307);
//通过accept()方法获取客户端的套接字对象
Socket socket = serverSocket.accept();
//通过获取的套接字获取输入流
InputStream is = socket.getInputStream();) {
int len = -1;
//写出信息,通过套接字将信息输出到客户端
byte[] flush = new byte[1024];
while ((len = is.read(flush)) != -1) {
System.out.println("__________________");
System.out.println("| "+new String(flush,0,len));
System.out.println("| from:"+socket.getInetAddress());
System.out.println("¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
- TCP网络编程:客户端发送文件给服务端,并保存在本地,服务器并返回一个数据告诉客户端上传成功了
public class demo02 {
public static void main(String[] args) {
new Thread(new SocketThread()).start();
new Thread(new ServerSocketThread()).start();
}
}
//客户端
class SocketThread implements Runnable {
@Override
public void run() {
//创建套接字对象
try(Socket socket = new Socket("127.0.0.1",3307);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("Net/src/testfile/test.txt"));
//获取套接字的输出流
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
//获取套接字的输入流
InputStream is = socket.getInputStream();) {
//数据写出
byte[] bytes = new byte[1024];
int len = -1;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes,0,len);
}
System.out.println("传输完成");
bos.flush();
//数据写出完毕后关闭输出流,否则服务端会一直进行接收数据
socket.shutdownOutput();
//读取服务器发回的信息
len = is.read(bytes);
System.out.println(new String(bytes,0,len));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 服务端
*/
class ServerSocketThread implements Runnable {
@Override
public void run() {
try(ServerSocket serverSocket = new ServerSocket(3307);
Socket socket = serverSocket.accept();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Net/src/testfile/test2.txt"));
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
OutputStream os = socket.getOutputStream();) {
byte[] bytes = new byte[1024];
int len = -1;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes,0,len);
}
bos.flush();
//传输完成后,客户端主动关闭客户端的输出流,那么服务端的输入流就会结束,
// 否则服务端一直会接收数据不停
//返回给客户端信息
os.write("已经收到了,谢谢".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
UDP编程
UDP优点
快,比TCP稍安全 UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制,系统不保证UDP数据包一定能到达,也不保证什么时候能到达,UDP是一个无状态的传输协议,所以它在传递数据时非常快。
Java使用DatagramSocket代表UDP协议的Socket,DatagramSocket本身只是码头,不维护状态,不能产生IO流,它的唯一作用就是接收和发送数据报,Java使用DatagramPacket来代表数据报,DatagramSocket接收和发送的数据都是通过DatagramPacket对象完成的。
发送端使用步骤
- 创建服务端+端口
- 准备数据
- 打包(发送的地点及端口)
- 发送资源
- 关闭资源
接收端使用步骤
-
创建服务端+端口
-
准备接收容器
-
封装成包
new DatagramPacket(byte[] b,int length)
-
接收数据,使用
DatagramSocket
的实例的receive(DatagramPacket)
方法进行接收阻塞式接收,直到接收到一个数据为止
-
分析数据
-
关闭资源
示例
- 发送端发生一句话,接收端接收并显示
public class demo01 {
public static void main(String[] args) {
new Thread(new Send()).start();
new Thread(new Receive()).start();
}
}
//发送端
class Send implements Runnable {
@Override
public void run() {
//1. 创建客户端,DatagramSocket只负责收发数据
DatagramSocket socket = null;
//2. 创建数据报,DatagramPacket来代表数据报
DatagramPacket packet = null;
//创建数据
byte[] data = "嘿嘿嘿,你好呀".getBytes();
try {
InetAddress inet = InetAddress.getLocalHost();
socket = new DatagramSocket();
//3. 打包数据,指明主机地址和端口号
packet = new DatagramPacket(data,0,data.length,inet,3307);
//4. 发送数据
socket.send(packet);
//5. 关闭数据
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(socket != null) {
socket.close();
}
}
}
}
//接收端
class Receive implements Runnable {
@Override
public void run() {
//1. 创建服务端,DatagramSocket只负责收发数据
DatagramSocket socket = null;
//2. 创建数据报,DatagramPacket来代表数据报
DatagramPacket packet = null;
try {
//3. 数据接收容器
byte[] data = new byte[100];
//4. 指明服务端端口
socket = new DatagramSocket(3307);
//5. 数据封装程包
packet = new DatagramPacket(data,0,data.length);
//6. 接收数据
socket.receive(packet);
//输出数据,通过getData()方法获取数据报存储的数据,getLength()获取数据的实际接收的长度
System.out.println(new String(packet.getData(),0,packet.getLength()));
//7. 关闭数据
socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(socket != null) {
socket.close();
}
}
}
}