- 网络编程的目的、网路编程的两个主要问题:1. 定位主机以及主机上的特定应用(解决办法:socket(即IP:Port)、2. 可靠传输 (解决办法:网络通信协议,如TCP/IP)
- ">
- 通信要素1: Socket(IP:Port) 。 IP对应InetAddress对象、socket对应Socket(InetAddress实例,port)对象、ServerSocket(port) 。
- 通信要素2: 网络协议,TCP/IP为例
- TCP网络编程: InetAddress类、Socket类、ServerSocket类
- UDP网络编程: DatagramSocket类
- URL编程:
- 片段名:锚点。
- 补充:tomcat - mac 的安装、启动
网络编程的目的、网路编程的两个主要问题:1. 定位主机以及主机上的特定应用(解决办法:socket(即IP:Port)、2. 可靠传输 (解决办法:网络通信协议,如TCP/IP)
通信要素1: Socket(IP:Port) 。 IP对应InetAddress对象、socket对应Socket(InetAddress实例,port)对象、ServerSocket(port) 。
注1: InetAddress.getByName()等来实例化,因其构造器不被外部访问。
注2:Socker和ServerSocket配套了相关IO流
(代码)InetAddress类
package xj.java;
import org.junit.jupiter.api.Test;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* @author jia
* @create 2021-12-02 1:33 下午
*/
public class SocketTest {
@Test
public void inetAddressTest(){
/*测试 socket实例(ip:port)的创建 */
try {
InetAddress inet1 = InetAddress.getByName("14.215.177.38"); // ip地址
InetAddress inet2 = InetAddress.getByName("www.baidu.com"); // 域名(通过dns服务器间接获取ip地址)
InetAddress inet3 = InetAddress.getByName("127.0.0.1"); // // 本地回路地址 方式一
InetAddress inet4 = InetAddress.getLocalHost(); // 本地回路地址 方式二
//
System.out.println(inet1); // /14.215.177.38
System.out.println(inet2); // www.baidu.com/14.215.177.38
System.out.println(inet3); // /127.0.0.1
System.out.println(inet4); // MacBook-Pro-9.local/127.0.0.1
//
System.out.println(inet2.getHostName()); // www.baidu.com
System.out.println(inet2.getHostAddress()); // 14.215.177.38
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
通信要素2: 网络协议,TCP/IP为例
TCP网络编程: InetAddress类、Socket类、ServerSocket类
/* 代码实现原理: 1。客户端会创建一个为了与对方连接的socket对象(根据对方的ip:port),会通过该socket发送连接请求,如果对方同意请求,那么会接收到该socket。 2。服务器端会创建一个new ServerSocket(service_port)对象,并使用accept()方法即可监听该自身的端口,并且在接收客户端的连接请求后会拿到客户端的socket。 3。当客户端和服务器产生连接后,双方都拿到了socket对象。 此时,客户端可通过socket.getOutputStream()可拿到输出流以发送数据。 此时,服务器可通过socket.getInputStream()拿到输入流以接收数据。
* 代码运行过程:
* 1。 先运行 service_socket() 来监听 客户端发来的请求连接。
* 2。 运行client_socket来拿到定位服务器的Socket。
* 3。 之后便使用socket中提供的io流和本地的io来传输数据了。
(代码1 TCP : 客户端发送图片 + 服务器文字反馈)( 注意:文本特殊性,接收方要使用ByteArrayOutputStream流来接收字节数据)
package xj.java;
import org.junit.jupiter.api.Test;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author jia
* @create 2021-12-02 4:54 下午
*/
/**
* 实现原理:
* 1。客户端会创建一个为了与对方连接的socket对象(根据对方的ip:port),会通过该socket发送连接请求,如果对方同意请求,那么会接收到该socket。
* 2。服务器端会创建一个new ServerSocket(service_port)对象,并使用accept()方法即可监听该自身的端口,并且在接收客户端的连接请求后会拿到客户端的socket。
* 3。当客户端和服务器产生连接后,双方都拿到了socket对象。
* 此时,客户端可通过socket.getOutputStream()可拿到输出流以发送数据。
* 此时,服务器可通过socket.getInputStream()拿到输入流以接收数据。
*
* * 代码运行过程:
* * 1。 先运行 service_socket() 来监听 客户端发来的请求连接。
* * 2。 运行client_socket来拿到定位服务器的Socket。
* * 3。 之后便使用socket中提供的io流和本地的io来传输数据了。
*
* 注意:下面的测试,应该在try-catch-finally中完成,为了方便才使用throws
*/
public class SocketTest2 {
/*
* TCP发送图片文件
* socket.shutdownOutput(); // 发送完文件后,发送方一定要做!否者等待方不知道何时结束接受,将被阻塞。
* */
@Test
public void client_socket() throws IOException {
/*客户端,从硬盘读取文件,并向服务器端发送字节数据*/
// des_ip 和 des_port 目的是为与对方连接而创建一个socket,用于定位服务器中特定应用的地址。
String des_ip = "127.0.0.1";
int des_port = 12345;
// 定义一些缓冲区
byte[] buf = new byte[10];
int buf_len = 0;
// 1 创建一个为了与对方连接的socket。
Socket socket = new Socket(InetAddress.getByName(des_ip), des_port);
// 2 从socket获得输出流\输入流
OutputStream socket_os = socket.getOutputStream();
InputStream socket_is = socket.getInputStream();
// 3 发送一张图片给对方:从本地获得的字节数据并发送给对方
InputStream pic_bis = new BufferedInputStream(new FileInputStream("client_pic.png"));
while ((buf_len = pic_bis.read(buf)) != -1) { // 将本地数据保存到缓冲区buf
socket_os.write(buf, 0, buf_len); // 将buf中的数据发送给对方。
}
socket.shutdownOutput();
// 4 接受服务区的反馈文字,并打印
OutputStream word_baos = new ByteArrayOutputStream();
buf = new byte[10];
while ((buf_len = socket_is.read(buf)) != -1){
//(注意: 不要直接打印buf中数据,会中文乱码,因为发送和接收时都采用固定大小的缓冲区发送字节数据。解决办法是:用数组接收全部数据)
//System.out.println(buf.toString());
word_baos.write(buf,0,buf_len);
}
System.out.println(word_baos.toString());
socket.shutdownInput();
// 5 关闭流和socket
word_baos.close();
pic_bis.close();
socket.close();
socket_is.close();
socket_os.close();
}
@Test
public void service_socket() throws IOException {
/*服务器端,接收客户端发送的字节数据,并保存到硬盘*/
int service_port = 12345;
// 数据的缓冲区
byte[] buf = new byte[10];
int buf_len = 0;
// 1 创建 server_socket服务器套接字(ip参数可忽略,因为是服务器自身的套接字) ,并监听对此套接字的连接请求并接受它。
ServerSocket server_socket = new ServerSocket(service_port);
Socket socket = server_socket.accept(); // 监听服务器自身的service_port端口,如果有客户端的连接请求就接收它。
// 2 从socket获得输入流\输出流
InputStream socket_is = socket.getInputStream();
OutputStream socket_os = socket.getOutputStream();
// 3.2 socket输入流中获得图片数据,并保存到本地。
OutputStream pic_bos = new BufferedOutputStream(new FileOutputStream("server_pic.png"));
while ((buf_len = socket_is.read(buf)) != -1) {
pic_bos.write(buf, 0, buf_len);
}
socket.shutdownInput();
// 4 给对方发送反馈文字
socket_os.write("谢谢!我是服务器,我已经收到了你的图片".getBytes());
socket.shutdownOutput();
// 5 关闭流和socket
pic_bos.close();
socket_os.close();
socket_is.close();
socket.close();
server_socket.close();
}
}
UDP网络编程: DatagramSocket类
代码
URL编程:
比如,下载软件中的“种子,这个种子就是url。
代码
核心思路:从tomcat服务器中,拿到目标资源的输入流 HttpURLConnection.getInputStream()
。
补充:tomcat - mac 的安装、启动
思路:
tomcat的可执行程序和shell文件都在bin目录下,比如bin/startup.sh来启动tomcat,访问http://localhost:8080/ 即可。