IP
IP地址的API:java.net.InetAddress
IP地址分类:
-
IPV4 / IPV6
-
IPV4:如:127.0.0.1。4个字节(32bit)。42亿多(2^32)。30亿在北美,亚洲4亿。2011年用尽。
-
IPV6:如:fe80::5594:3b26:bd74:92dc%19。16个字节(128bit,8个无符号整数)。
-
-
公网 / 私网
- ABCD类地址
测试InetAddress
import java.net.InetAddress;
import java.net.UnknownHostException;
public class TestInetAddress {
public static void main(String[] args) {
try {
// 获取本机的IP
InetAddress ip1 = InetAddress.getByName("127.0.0.1");
System.out.println(ip1); // /127.0.0.1
InetAddress ip2 = InetAddress.getByName("localhost");
System.out.println(ip2); // localhost/127.0.0.1
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost); // Legion-Y7000P-2019-PG0/10.16.95.130
// 获取网站的ip
InetAddress ip3 = InetAddress.getByName("www.jd.com");
System.out.println(ip3); // www.jd.com/183.66.105.73
System.out.println(ip3.getAddress()); // [B@1b6d3586
System.out.println(ip3.getCanonicalHostName()); // 219.151.17.75
System.out.println(ip3.getHostAddress()); // 219.151.17.75
System.out.println(ip3.getHostName()); // www.jd.com
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
PORT
ip地址:代表服务器的具体地址
端口号:代表服务器中所提供的服务
ip+port:哪台服务器的哪个服务
端口号范围:0-65535
TCP、UDP:不同协议可以用相同的端口,不会冲突。单个协议下端口号不能冲突。
端口号分类:
公有端口:0-1023(如:http的80,https的443,ftp的21,telnet的23)
程序注册端口:1024-49151(如tomcat的80,mysql的3306,oracle的1521,redis的6379,rabbitmq的5672,15672)
动态端口、私有端口:49152-65535
windows:
netstat -ano:查看所有端口
netstat -ano|findstr "5900":查看指定的端口
tasklist|findstr "5500":查看指定端口的进程
ctrl + shift + esc:打开任务管理器
import java.net.InetSocketAddress;
public class TestInetSocketAddress {
public static void main(String[] args) {
InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 8080);
System.out.println(inetSocketAddress); // /127.0.0.1:8080
InetSocketAddress inetSocketAddress1 = new InetSocketAddress("www.jd.com", 443);
System.out.println(inetSocketAddress1); // www.jd.com/221.228.219.213:443
System.out.println(inetSocketAddress1.getAddress()); // www.jd.com/219.151.17.75
System.out.println(inetSocketAddress1.getHostName()); // www.jd.com
System.out.println(inetSocketAddress1.getHostString()); // www.jd.com
System.out.println(inetSocketAddress1.getPort()); // 443
}
}
协议
TCP
客户端Socket与服务端ServerSocket进行通信
客户端TcpClient:
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class TcpClient {
public static void main(String[] args) throws IOException {
Socket socket = null;
OutputStream os = null;
try {
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 4444;
socket = new Socket(address, port);
os = socket.getOutputStream();
os.write("客户端发送信息!".getBytes());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
socket.close();
}
}
}
}
服务端TcpServer
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
serverSocket = new ServerSocket(4444);
while (true){
socket = serverSocket.accept(); // 服务端一直监听
is = socket.getInputStream();
baos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while ((len = is.read(bytes)) != -1){
baos.write(bytes, 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 (is != null) {
try {
is.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();
}
}
}
}
}
客户端Socket与服务端ServerSocket收发文件
服务端
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServerGetFile {
/*
服务端通过输入流读取客户端发来的文件
*/
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
FileOutputStream fos = null;
OutputStream os = null;
serverSocket = new ServerSocket(1234);
socket = serverSocket.accept();
is = socket.getInputStream(); // 获得文件流对象
int len;
byte[] buffer = new byte[1024];
fos = new FileOutputStream("test/1.md");
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
// 通知客户端接收完毕
os = socket.getOutputStream();
os.write("接受完毕,请客户端断开连接!".getBytes());
os.close();
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
客户端
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class TcpClientSendFile {
/*
客户端通过socket获得输出流,输出文件
*/
public static void main(String[] args) throws Exception {
Socket socket = null;
FileInputStream fis = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
OutputStream os = null;
socket = new Socket(InetAddress.getByName("127.0.0.1"), 1234);
fis = new FileInputStream(new File("test/socket.md"));
os = socket.getOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
// 通知服务器传输结束
socket.shutdownOutput();
is = socket.getInputStream();
baos = new ByteArrayOutputStream();
byte[] buffer2 = new byte[1024];
int len2;
while ((len2 = is.read(buffer2)) != -1) {
baos.write(buffer2, 0, len2);
}
System.out.println(baos.toString());
os.close();
baos.close();
is.close();
fis.close();
socket.close();
}
}
UDP
没有客户端和服务端的概念,只有发送端和接收端的概念
UdpSend.java
package udp;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UdpSend {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(5678);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String msg = br.readLine();
DatagramPacket packet = new DatagramPacket(
msg.getBytes(),
0,
msg.getBytes().length,
InetAddress.getByName("127.0.0.1"),
1234);
socket.send(packet);
if ("bye".equals(msg)) {
break;
}
}
// 关闭资源
socket.close();
}
}
UdpRec.java
package udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UdpRec {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(1234);
byte[] buffer = new byte[1024];
while (true) {
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
socket.receive(packet);
// System.out.println(packet.getAddress().getHostAddress());
String data = new String(packet.getData(), 0, packet.getLength());
System.out.println(data);
if ("bye".equals(data)) {
break;
}
}
socket.close();
}
}
实习学生和老师聊天:SendTask.java、RecTask.java、Student.java、Teacher.java
使用多线程调度实现
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class SendTask implements Runnable {
private int fromPort;
private int toPort;
private String toIp;
private DatagramSocket socket;
private BufferedReader reader;
public SendTask(int fromPort, int toPort, String toIp) {
this.fromPort = fromPort;
this.toPort = toPort;
this.toIp = toIp;
try {
this.socket = new DatagramSocket(this.fromPort);
reader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true) {
try {
String msg = reader.readLine();
DatagramPacket packet = new DatagramPacket(
msg.getBytes(),
0,
msg.getBytes().length,
InetAddress.getByName(toIp),
toPort);
socket.send(packet);
if ("bye".equals(msg)) {
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 关闭资源
socket.close();
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class RecTask implements Runnable{
private int port;
private DatagramSocket socket;
public RecTask(int port) {
this.port = port;
init();
}
private void init() {
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
try {
socket.receive(packet);
String data = new String(packet.getData(), 0, packet.getLength());
System.out.println(packet.getAddress().getHostAddress() + "/" + port + ": " + data);
if ("bye".equals(data)) {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
package udp;
public class Student {
public static void main(String[] args) {
new Thread(new SendTask(1111, 2222, "127.0.0.1")).start();
new Thread(new RecTask(3333)).start();
}
}
package udp;
public class Teacher {
public static void main(String[] args) {
new Thread(new SendTask(4444, 3333, "127.0.0.1")).start();
new Thread(new RecTask(2222)).start();
}
}