网络编程
IP地址
- InetAddress类实现
- 唯一定位一台计算机。
- IP地址分类
- IPv4/Ipv6:IPv4 32位组成,IPv6 128位。
- 公网(互联网),私网(局域网)
- 192.168.x.x 专门给组织使用
- ABC类地址
- 域名:解决IP地址记忆问题
InetAddress inetAddress = InetAddress.getByName("127.0.0.1")
端口
-
端口表示计算机上的一个程序的进程。
-
不同进程有不同的端口号。端口范围:0-65535(TCP和UDP分别有65536个)
-
端口分类:
- 公有端口:0-1023
- http:80
- https:43
- ftp:21
- telent:23
- 程序注册端口:1024-49151,分配给用户或者程序
- Tomcat:8080
- MySQL:3306
- Oracle:1521
- 公有端口:0-1023
-
动态、私有:49152-65535
netstat -ano --查看所有端口
-
InetSocketAddress类实现
InetSocketAddress socketAddress = new InetSocketAddress(IP,port);
通信协议
-
**TCP/IP协议簇:**TCP:用户传输协议,UDP:用户数据报协议。TCP:连接,稳定(三次握手,四次分手)。UDP:不连接,不稳定。
-
客户端和服务器交互步骤(TCP):
-
客户端:
- 连接服务器socket
- 输出流发送消息Outputstream
-
服务器:
- 建立服务器的端口ServerSocket
- 等待用户接入accept
- 接收用户消息。InputStream
客户端:
package chat; import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; public class Client { public static void main(String[] args) { Socket socket = null; OutputStream ops = null; try { //创建IP地址 InetAddress ip = InetAddress.getByName("127.0.0.1"); //端口 int port = 4040; //创建socket socket = new Socket(ip,port); //发送消息输出流 ops = socket.getOutputStream(); //向服务器端发送消息 ops.write("2020.7.27".getBytes()); } catch (Exception e) { e.printStackTrace(); } finally { if(ops!=null){ try { ops.close(); } catch (IOException e) { e.printStackTrace(); } } if(socket!=null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
服务器:
-
package chat;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream ips = null;
ByteArrayOutputStream baos = null;
try {
//创建服务器端口
serverSocket = new ServerSocket(4040);
//等待客户端连接
socket = serverSocket.accept();
//创建输入流,接收客户端消息
ips = socket.getInputStream();
//管道流解决消息乱码问题
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len ;
while((len = ips.read(buffer))!=-1){
baos.write(buffer,0,len);
}
System.out.println(baos.toString());
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if(baos!=null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ips!=null){
try {
ips.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(serverSocket!=null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- 文件上传(TCP实现)
服务器:
package fileUpload;
import jdk.internal.util.xml.impl.Input;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream ips = null;
FileOutputStream fos = null;
OutputStream ops = null;
try {
//创建端口
serverSocket = new ServerSocket(9090);
//等待连接
socket = serverSocket.accept();
//输入流,接收数据
ips = socket.getInputStream();
byte[] buffer = new byte[1024];
int len;
//文件输出流,保存数据
fos = new FileOutputStream(new File("girl.jpg"));
while((len = ips.read(buffer))!=-1){
fos.write(buffer,0,len);
}
//接收完毕,发送应答
ops = socket.getOutputStream();
ops.write("上传成功".getBytes());
}
catch (IOException e) {
e.printStackTrace();
}
finally {
ops.close();
fos.close();
ips.close();
socket.close();
serverSocket.close();
}
}
}
客户端
package fileUpload;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class Client {
public static void main(String[] args) {
Socket socket = null;
ByteArrayOutputStream baos = null;
InputStream ips = null;
OutputStream ops = null;
FileInputStream fis = null;
int len;
try {
//socket连接
socket = new Socket(InetAddress.getByName("127.0.0.1"),9090);
//读取文件
fis = new FileInputStream(new File("./src/fileUpload/beautifulGirl.jpg"));
byte [] fileBuffer = new byte[1024];
//输出流发送数据
ops = socket.getOutputStream();
while((len = fis.read(fileBuffer))!=-1){
ops.write(fileBuffer,0,len);
}
//通知服务器,发送完毕
socket.shutdownOutput();
//等待服务器发送完毕指令
try {
ips = socket.getInputStream();
byte[] buffer = new byte[1024];
baos = new ByteArrayOutputStream();
while((len = ips.read(buffer))!=-1){
baos.write(buffer,0,len);
}
System.out.println(baos.toString());
}
catch (IOException e) {
e.printStackTrace();
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if(baos!=null){
try {
baos.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
if(ips!=null){
try {
ips.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
if(ops!=null){
try {
ops.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Tomcat
- 服务器:Tomcat服务器
- 客户端:浏览器
UDP
-
无需连接,需要知道对方地址。
-
通信步骤:
发送端:
- 建立socket。DatagramSocket
- 建包。DatagramPacket
- 发送包。socket.send()
- 关闭socket
接收端:
- 创建端口。DatagramSocket
- 接收数据包。DatagramPacket,socket.receive()。
- 关闭socket。
发送端:
package UDPCom; import java.net.*; public class UDPSend { public static void main(String[] args) throws Exception { //建立socket DatagramSocket socket = new DatagramSocket(); //建立发送包 InetAddress ip = InetAddress.getByName("127.0.0.1"); int port = 9900; String msg = "Hello Receiver"; DatagramPacket dataPacket = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,ip,port); //发送数据包 socket.send(dataPacket); //关闭socket socket.close(); } }
接收端:
package UDPCom; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; public class UDPReceive { public static void main(String[] args) throws IOException { //创建端口 DatagramSocket socket = new DatagramSocket(9900); //接收数据包 byte[] buffer = new byte[1024]; DatagramPacket dataPacket = new DatagramPacket(buffer,0,buffer.length); socket.receive(dataPacket); System.out.println(new String(dataPacket.getData(),0,dataPacket.getLength())); //关闭socket socket.close(); } }
-
UDP实现聊天
发送线程
package UDPChat;
import java.awt.image.DataBuffer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class SendThread implements Runnable {
//端口和IP地址
private String receiverIp;
private int receiverPort;
DatagramSocket socket = null;
BufferedReader buffer = null;
InetAddress ip = null;
public SendThread(String receiverIp,int receiverPort){
this.receiverIp = receiverIp;
this.receiverPort = receiverPort;
try {
//创建socket
socket = new DatagramSocket();
//创建数据包
ip = InetAddress.getByName(receiverIp);
//控制台输入数据
buffer = new BufferedReader(new InputStreamReader(System.in));
}
catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
//循环发送消息
while(true){
try {
//读取控制台数据
String data = buffer.readLine();
DatagramPacket packet = new DatagramPacket(data.getBytes(),0,data.getBytes().length,ip,receiverPort);
//发送数据
socket.send(packet);
//退出聊天
if(data.equals("quit")){
buffer.close();
socket.close();
break;
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
接收线程
package UDPChat;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ReceiveThread implements Runnable {
//端口
private int port;
private String name;
DatagramSocket socket = null;
DatagramPacket packet = null;
public ReceiveThread(int port ,String name){
this.port = port;
this.name = name;
try {
//创建端口
socket = new DatagramSocket(port);
}
catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(true){
try {
//接收数据
byte[] buffer = new byte[1024];
packet = new DatagramPacket(buffer,0,buffer.length);
socket.receive(packet);
String msg = new String(packet.getData(),0,buffer.length);
System.out.println(name+":"+msg);
//退出聊天
if(msg.equals("quit")){
socket.close();
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
老师
package UDPChat;
public class Teacher {
public static void main(String[] args) {
new Thread(new SendThread("127.0.0.1",9900)).start();
new Thread(new ReceiveThread(9000,"学生")).start();
}
}
学生
package UDPChat;
public class Student {
public static void main(String[] args) {
new Thread(new SendThread("127.0.0.1",9000)).start();
new Thread(new ReceiveThread(9900,"老师")).start();
}
}
URL
- 统一资源定位符,定位互联网上的资源。
- URL组成:协议://IP:端口/项目名/具体的文件
- 下载资源:
package URL;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class DownloadRes {
public static void main(String[] args) throws Exception {
//定义URL类
URL url = new URL("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1595922124628&di=f672e12476bc6218bd37f613a59f75eb&imgtype=0&src=http%3A%2F%2F01.minipic.eastday.com%2F20170113%2F20170113174441_4a700387e67e0119e06a111ee2292bf7_10.jpeg");
//连接URL资源
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//获取资源输入流
InputStream ips = urlConnection.getInputStream();
FileOutputStream ous = new FileOutputStream(new File("girl.jpg"));
byte[] buffer = new byte[1024];
int len;
while((len = ips.read(buffer))!=-1){
ous.write(buffer,0,buffer.length);
}
ous.close();
ips.close();
urlConnection.disconnect();
}
}