目录
14.1 网络编程的概述
package com.pfl.java1;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
*
* 一、网络编程中有两个主要的问题:
* 1.如何准确的定位网络上的一台或多台主机;定位主机上的特定应用
* 2.找到主机后如何可靠高效的进行数据传输
*
* 二、网络编程中的两个要素:
* 1.对应问题一:IP 和 端口号
* 2.对应问题二:提供网络通信协议:TCP/IP参考模型(应用层、传输层、网络层、数据链路层、物理层)
*
* 三、通信要素一:IP和端口号
*
* 1. IP:唯一的标识Internet上的计算机(通信实体)
* 2. 在Java中使用InetAddress类代表IP地址
* 3. IP的分类 IPv4 和 IPv6;万维网 和 局域网
* 4. 域名: www.baidu.com www.mi.com www.sina.com
* 5. 本地回路地址:127.0.0.1 对应着:localhost
* 6. 如何实例化InetAddress:两个方法:getByName(String host) 和 getLocalHost()
* 两个常用方法:getHostName() / getHostAddress()
*
* 7. 端口号:正在计算机上运行的进程。
* 要求:不同的进程有不同的端口号
* 范围:被规定为一个16位的整数 0~65535。
*
* 8. 端口号与IP地址的组合得出一个网络套接字:Socket
* 网络通信也可以叫做Socket通信,Socket编程
*
* @author pflik-
* @create 2022-02-08 13:00
*/
public class InetAddressTest {
public static void main(String[] args) {
try {
InetAddress inet1 = InetAddress.getByName("192.168.10.14");
//inet1 就是对应着一个IP地址:"192.168.10.14"
System.out.println(inet1);
InetAddress inet2 = InetAddress.getByName("www.atguigu.com");
System.out.println(inet2);
InetAddress inet3 = InetAddress.getByName("127.0.0.1");
System.out.println(inet3);
//获取本机的IP
InetAddress inet4 = InetAddress.getLocalHost();
System.out.println(inet4);
//getHostName()
System.out.println(inet2.getHostName());
//getHostAddress()
System.out.println(inet2.getHostAddress());
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
14.2 网络通信要素概述
14.3 通信要素1:IP和端口号
14.4 通信要素2:网络协议
建立链接
的时候–三次握手
:
14.5 TCP网络编程
例题
例题一:客户端发送内容给服务端,服务端将内容打印到控制台上。
package com.pfl.java1;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 实现TCP的网络编程
* 例子1:客户端发送一段信息给服务端,服务端将数据显示在控制台上
*
*
*
* 快捷键:
* Alt+Enter:提示处理报错情况
* ctrl+Alt+T:处理异常try-catch-finally
* ctrl+shift+上/下键:将选择的代码上下移动
*
* @author pflik-
* @create 2022-02-08 18:56
*/
public class TCPTest1 {
//注意:要先要启动服务端,在启动客户端
//需求一:客户端给服务端发一句话
//需求二:想看一下是谁发给服务端的
//测试单元-客户端
@Test
public void client() {
//发送数据
Socket socket = null;
OutputStream os = null;
try {
//1.创建Socket对象,指明服务器端的IP和端口号
//获取对方(服务器端)的IP
InetAddress inet = InetAddress.getByName("127.0.0.1");
//创建一个Socket,里面包含(对方)具体的IP和端口号
socket = new Socket(inet,8899);
//2.获取一个输出流,用于输出数据
//传输数据-发送
os = socket.getOutputStream();
//3.写出数据的操作
os.write("你好,我是客户端mm".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.资源的关闭
//socket也是资源,类似与一个流一样,也需要关闭
if(os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//有了close
// 1.就需要上面的异常使用try-catch-finally
// 2.在finally中关闭流和socket
// 3.并且针对每个close()都要try...catch一下即可
}
//测试单元-服务端
@Test
public void server() {
//接受数据/操作数据
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
//1.创建服务器端的Socket:ServerSocket,指明自己的端口号
//同样对应是socket,在服务器中使用的ServerSocket--有异常就先throws一下
ss = new ServerSocket(8899);
//2.调用accept()表示接受来自于客户端的socket
//用来接受来自客户端的Socket
socket = ss.accept();
//3.获取输入流
//读入流
is = socket.getInputStream();
//想要把流动的数据显示到控制台上
// 1.用read读出来
// 2.不过发送的数据比较长,使用循环,并且需要长的byte数组
//思路一:
//不建议这样写,可能会有乱码
//注:因为在客户端输入的是汉字,我们使用的是字节流(根据UTF-8,一个汉字占3个字节)
//可以把byte数组大一些(汉字可以更多,不能确定有多少个字节)
// 不过如果byte数组很小的话,在还原成String的时候就会出问题
//所以这样是不可以的。
// byte[] buffer = new byte[20];
// int len;
// while((len = is.read(buffer)) != -1) {
// //发送的是文本,这时候需要转成String
// String str = new String(buffer, 0, len);
// System.out.print(str);
// }
//思路二:
//引入新的知识--ByteArrayoutputStream
//4.读取输入流中的数据
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[5];
int len;
while((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
//那么这个数据写到哪里了呐?
//baos也没有像原先的流一样指定文件
//其实ByteArrayOutputStream有一个数组,往里面写就可以,不够会自己扩充
//byte数组的大小是5,那么就是每次往baos里面写进去,先拼接好
// 直到最后输入完成,开一个大的数组把全部内容(好多个大小为5的byte)还原为字符串
}
//这样就不会出现乱码的问题
System.out.println(baos.toString());
//这样就把数据输出到控制台上了
//服务端接受的是客户端的socket,所以可以通过soket来获取客户端的信息
//socket.getInetAddress():获取IP
//socket.getInetAddress().getHostAddress():看一下IP的地址
System.out.println("收到了来自于: " + socket.getInetAddress().getHostAddress() + "的数据");
} catch (IOException e) {
e.printStackTrace();
} finally {
//5.资源的关闭
//关闭资源--流,
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 (IOException e) {
e.printStackTrace();
}
}
if(ss != null) {
try {
ss.close();//服务器不想接受了,才把ServerSocket关掉
} catch (IOException e) {
e.printStackTrace();
}
}
}
//注:
// 涉及到资源的关闭,保证他一定能够执行,所以不能使用throws
//需要把close之前的都要包起来
//把资源关闭命令都放到finally中,并且把每个命令之前都要判断一下是否为'null'
//在if判断后,把每个关闭命令都要try...catch一下
}
}
例题二:客户端发送文件给服务端,服务端将文件保存在本地。
代码一–简化版:
package com.pfl.java1;
import org.junit.Test;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 实现TCP的网络编程
* 例题2.客户端发送文件给服务端,服务端将文件保存在本地。
*
* @author pflik-
* @create 2022-04-27 20:59
*/
public class TCPTest2 {
//注意:因为涉及到资源的关闭,不能使用throws解决问题
//为了熟悉流程,只写成这样,可以参考例子一:里面有详细的内容
@Test
public void client() throws IOException {
//1.创建Socket
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
//2.获取一个输出流
//socket需要往外传数据
OutputStream os = socket.getOutputStream();
//输出的数据是从客户端本地发出的文件
//需要把文件读进来--为了效率,可以用缓冲流包一下
//3.获取一个输入流
FileInputStream fis = new FileInputStream(new File("Basketball-Kobe.jpg"));
//接下来就是具体的读、写的过程了
//4.读写过程
byte[] buffer = new byte[1024];
int len;
//read到buffer中,返回值不等于-1
while( (len = fis.read(buffer))!= -1) {
os.write(buffer, 0, len);
}
//5.资源的关闭
fis.close();
os.close();
socket.close();
}
@Test
public void server() throws IOException {
//1.造一个ServerSoket-指明自己的端口号
ServerSocket ss = new ServerSocket(9090);
//2.获取客户端的socket
Socket socket = ss.accept();
//3.获取客户端的一个输入流
//获取一个读入-输入流
InputStream is = socket.getInputStream();
//4.保存数据到本地,建一个本地的操作
FileOutputStream fos = new FileOutputStream(new File("Basketball-LeBron.jpg"));
//5.读写的过程
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
//此时这个文件就写出去了,写到fos里面去了
}
//6.资源的关闭
fos.close();
is.close();
socket.close();
ss.close();
}
}
代码二-完整版:
package com.pfl.java1;
import org.junit.Test;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 实现TCP的网络编程
* 例题2.客户端发送文件给服务端,服务端将文件保存在本地。
*
* @author pflik-
* @create 2022-04-27 20:59
*/
public class TCPTest2 {
//注意:这里涉及到的异常,应该使用try-catch-finally处理
// 因为涉及到资源的关闭,不能使用throws解决问题
//为了熟悉流程,只写成这样,可以参考例子一:里面有详细的内容
@Test
public void client() {
Socket socket = null;
OutputStream os = null;
FileInputStream fis = null;
try {
//1.创建Socket
socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
//2.获取一个输出流
//socket需要往外传数据
os = socket.getOutputStream();
//输出的数据是从客户端本地发出的文件
//需要把文件读进来--为了效率,可以用缓冲流包一下
//3.获取一个输入流
fis = new FileInputStream(new File("Basketball-Kobe.jpg"));
//接下来就是具体的读、写的过程了
//4.读写过程
byte[] buffer = new byte[1024];
int len;
//read到buffer中,返回值不等于-1
while( (len = fis.read(buffer))!= -1) {
os.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//5.资源的关闭
if(fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void server() {
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
FileOutputStream fos = null;
try {
//1.造一个ServerSoket-指明自己的端口号
ss = new ServerSocket(9090);
//2.获取客户端的socket
socket = ss.accept();
//3.获取客户端的一个输入流
//获取一个读入-输入流
is = socket.getInputStream();
//4.保存数据到本地,建一个本地的操作
fos = new FileOutputStream(new File("Basketball-LeBron.jpg"));
//5.读写的过程
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
//此时这个文件就写出去了,写到fos里面去了
}
System.out.println("接受成功!!!");
} catch (IOException e) {
e.printStackTrace();
} finally {
//6.资源的关闭
if(fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
P626