Java基础10-网络编程
概述
- 计算机网络:将多台计算机通过线路设备连接起来,在网络操作系统、网络管理软件和网络通信协议下实现资源共享,信息传递。
- 网络编程的目的:实现信息交流,数据交换,通信
- 如何实现?
- 定位主机
- 建立连接
- 进行通信
网络通信要素
- IP地址
- 定义一台主机
- 分类:
- ip地址分类:IPV4 IPV6
- IPV4:四个字节组成,总共只有42亿个地址
- IPV6:128位,8个无符号整数
- 公网(互联网),私网(局域网)
- ip地址分类:IPV4 IPV6
- 结构模式
- Javaweb:网页编程 B/S
- 网络编程:TCP/IP C/S
- 网络通信协议
- 网络通信协议:TCP 、 UDP
- TCP/IP参考模型
- 端口
- 表示计算机上的一个进程
- 不同的进程有不同的端口号,用来区分程序
- 区间0~65535
- 端口分类
- 共有端口0~1023
- HTTP:80
- HTTPS:443
- FTP:21
- Telent:23
- 程序注册端口1024~49151
- Tomcat:8080
- Mysql:3306
- Oracle:1521
- 动态、私有49152~65535
netstat -ano #查看所有的端口 netstat -ano|findstr "5900" #查看指定的端口 tasklist|findstr "8696" #查看指定端口的进程
- 共有端口0~1023
通信协议
- 一种约定(例子:三孔插座),大家都按照某个约定做,就可以建立通信
- 网络通信协议:速率、传输码率、代码结构、传输控制
- 问题:很复杂
- 所以将整个通信分了层
- TCP/IP协议簇 很多协议
- TCP:用户传输协议
- 需要建立连接、稳定
- 需要建立连接才能通信
- 三次握手建立连接(最少需要三次,保证稳定的连接),四次挥手断开连接
- 客户端、服务端
- 传输完成,释放连接,效率低
- UDP:用户数据报协议
- 不需要建立连接、不稳定
- 只管发送不管发送的结果如何
- 客户端服务端没有明确的界限
- IP:网络互联协议
TCP - Demo
package com.gaopeng.internet;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
//创建一个服务端
public class ServerSocketTest {
public static void main(String[] args) throws Exception {
//1.给自己一个设置一个端口号
ServerSocket serverSocket = new ServerSocket(9990);
//2.等待客户端进行连接
Socket accept = serverSocket.accept();
//3.读取客户端消息
InputStream inputStream = accept.getInputStream();
//4.创建管道流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int len;
while ((len= inputStream.read(buf))!=-1){
byteArrayOutputStream.write(buf,0,len);
}
System.out.println(byteArrayOutputStream.toString());
//5.关闭资源 (后开先关原则)
byteArrayOutputStream.close();
inputStream.close();
accept.close();
serverSocket.close();
}
}
package com.gaopeng.internet;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
//创建客户端
public class ClientSocketTest {
public static void main(String[] args) {
//1.获取服务器的IP地址和端口号
InetAddress byIP = null;
OutputStream outputStream=null;
Socket socket=null;
try {
byIP = InetAddress.getByName("127.0.0.1");
int port = 9990;
//2.创建连接
socket = new Socket(byIP, port);
//3.发送IO流消息
outputStream = socket.getOutputStream();
outputStream.write("你在干什么呢?".getBytes());
} catch (Exception e) {
e.printStackTrace();
}finally{
//关闭资源,关闭前先进行判断
if(outputStream!=null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- 总结:
- 服务端的创建:
- 设置端口号
- 等待客户端连接
- 读取客户端发送的信息(IO流操作)
- 关闭资源
- 客户端你的创建:
- 获取服务器IP地址和端口号
- 创建连接
- 发送IO流消息
- 关闭资源
- 服务端的创建:
TCP文件上传Demo
package com.gaopeng.internet;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//服务器
public class ServerSocketTest01 {
public static void main(String[] args) throws Exception {
//1.建立一个端口
ServerSocket serverSocket = new ServerSocket(9991);
//2.等待客户端连接
Socket accept = serverSocket.accept();
//3.读取客户端发送的信息
InputStream inputStream = accept.getInputStream();
//4.文件输出
FileOutputStream fileOutputStream = new FileOutputStream(new File("333.jpg"));
byte[] buf = new byte[1024];
int len=0;
while ((len = inputStream.read(buf))!=-1){
fileOutputStream.write(buf,0,len);
}
//5.通知客户端接收完毕,
OutputStream outputStream = accept.getOutputStream();
outputStream.write("服务器:接收完毕!".getBytes());
//6.关闭资源
outputStream.close();
fileOutputStream.close();
accept.close();
serverSocket.close();
}
}
package com.gaopeng.internet;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
//客户端
public class ClientSocketTest01 {
public static void main(String[] args) throws Exception {
//1.获取IP地址和端口
InetAddress byName = InetAddress.getByName("127.0.0.1");
int port = 9991;
//2.建立连接
Socket socket = new Socket(byName, port);
//3.创建一个输出流
OutputStream outputStream = socket.getOutputStream();
//4.读取文件
FileInputStream fileInputStream = new FileInputStream(new File("D:\\桌面\\头像.jpg"));
//5.写文件
byte[] buf = new byte[1024];
int len=0;
while ((len=fileInputStream.read(buf))!=-1){
outputStream.write(buf,0,len);
}
//6.通知服务器,我上传结束
socket.shutdownOutput();//我已传输完成
//7.确定服务器接收完毕,断开连接
InputStream inputStream = socket.getInputStream();
//8.创建管道流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buf2 = new byte[1024];
int len2=0;
while ((len2=inputStream.read(buf2))!=-1){
byteArrayOutputStream.write(buf2,0,len2);
}
//接收到服务器发送的,完成消息
System.out.println(byteArrayOutputStream.toString());
//关闭资源
byteArrayOutputStream.close();
inputStream.close();
fileInputStream.close();
outputStream.close();
socket.close();
}
}
- 总结:本质就是客户端与服务器多进行了几次通信
Tomcat
- 概念:
- web应用服务器
- 轻量级,性能稳定,免费开源
- 具有处理HTML页面的功能,另外他还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式。
- 适用于中小型系统
- 服务器的定义:
- 就是代码编写的一个可以根据用户请求实时的调用执行对应的逻辑代码的一个容器。(本质,是一个应用程序)。将服务器安装在操作系统上,将事先写好的业务逻辑处理代码根据规则放到服务器的指定位置,启动服务器,然后访问服务器的时候就会根据,请求调用具体的逻辑代码进行请求处理。
- Tomcat安装目录
\Backup 运行时备份基础的配置
\bin 存放启动和关闭Tomcat的可执行文件
\conf 存放Tomcat配置文件
\lib jar库文件
\logs 日志文件
\temp 临时文件
\webapps 存放web应用,默认在这里读取项目
\work 存放JSP转换后的Servlet文件
Tomcat依赖于JDK运行
UDP消息发送
package com.gaopeng.internet;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
//接收端
public class UDPServerTest01 {
public static void main(String[] args) throws Exception {
//1.设置开发端口
DatagramSocket datagramSocket = new DatagramSocket(9992);
//2.准备接收数据包
byte[] buf = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(buf, 0, buf.length);
datagramSocket.receive(datagramPacket);
System.out.println(datagramPacket.getAddress().getHostAddress());
//3.将需要打印的数据进行格式转换
System.out.println(new String(datagramPacket.getData(),0,datagramPacket.getData().length));
datagramSocket.close();
}
}
package com.gaopeng.internet;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
//发送端
public class UDPClientTest01 {
public static void main(String[] args) throws Exception {
// 1.建立一个Socket
DatagramSocket datagramSocket = new DatagramSocket();
// 2.创建包
String msg="只要学不死,就往死里学!";
InetAddress localhost = InetAddress.getByName("localhost");
int port=9992;
//参数的列表分别是:数据,数据长度-起始,数据长度-结束,IP地址,端口号
DatagramPacket datagramPacket = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
// 3.发送包
datagramSocket.send(datagramPacket);
// 4.关闭资源
datagramSocket.close();
}
}
- 总结:发送数据包
UDP多线程,在线聊天Demo
//发送工具类
package com.gaopeng.internet;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class UDPSendTest02 implements Runnable{
private int fromPort;
private String toIP;
private int toPort;
DatagramSocket socket;
BufferedReader reader;
public UDPSendTest02(int fromPort, String toIP, int toPort) {
this.fromPort = fromPort;
this.toIP = toIP;
this.toPort = toPort;
try {
socket = new DatagramSocket(fromPort);
//准备数据:读取控制台 System.in
reader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try {
String data = reader.readLine();
byte[] datas = data.getBytes();
DatagramPacket datagramPacket = new DatagramPacket(datas,0,datas.length,new InetSocketAddress(this.toIP,this.toPort));
socket.send(datagramPacket);
if (data.equals("end")){
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
socket.close();
}
}
//接收工具类
package com.gaopeng.internet;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
//接收消息方
public class UDPReceiveTest02 implements Runnable{
DatagramSocket socket;
private int fromPort;
private String msgFrom;
public UDPReceiveTest02(int fromPort, String msgFrom) {
this.fromPort = fromPort;
this.msgFrom = msgFrom;
try {
socket = new DatagramSocket(fromPort);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try {
//准备接收包裹
byte[] buf = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(buf, 0, buf.length);
socket.receive(datagramPacket);
//断开连接end
byte[] data = datagramPacket.getData();
String dataStr = new String(data, 0, data.length);
System.out.println(msgFrom+":"+dataStr);
if (dataStr.equals("end")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
//实例
//学生
public class Student {
public static void main(String[] args) {
//开启一个接收端
new Thread(new UDPReceiveTest02(9995,"老师")).start();
//开启一个发送端
new Thread(new UDPSendTest02(9994,"127.0.0.1",9993)).start();
}
}
//老师
public class Teacher {
public static void main(String[] args) {
//开启一个接收端
new Thread(new UDPReceiveTest02(9993,"学生")).start();
//开启一个发送端
new Thread(new UDPSendTest02(9996,"127.0.0.1",9995)).start();
}
}