一、 IP
package com.zlf.network;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class TestInetAddress {
public static void main(String[] args) {
try {
// 查询本机地址
InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
System.out.println(inetAddress1);
InetAddress inetAddress2 = InetAddress.getByName("localhost");
System.out.println(inetAddress2);
InetAddress inetAddress3 = InetAddress.getLocalHost();
System.out.println(inetAddress3);
// 查询网站ip地址
InetAddress inetAddress5 = InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress5);
System.out.println("*****************常用方法**************");
// 常用方法
System.out.println(inetAddress5.getAddress());//
System.out.println(inetAddress5.getCanonicalHostName());//获取规范的名字
System.out.println(inetAddress5.getHostAddress()); //获取ip
System.out.println(inetAddress5.getHostName());//域名或者自己电脑的名字
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
输出结果
/127.0.0.1
localhost/127.0.0.1
DESKTOP-UTDKEAA/192.168.184.1
www.baidu.com/39.156.66.14
*****************常用方法**************
[B@6e8cf4c6
39.156.66.14
39.156.66.14
www.baidu.com
Process finished with exit code 0
二、端口
端口被规定:0~65535
端口分类
- 共有端口:0~1023
HTTP:80
HTTPS:443
FTP:21
Telent:23 - 程序注册端口:1024~49151
Tomcat:8080
MySQL:3306
Oracle:1521
DOS命令查看端口
- 查看所有端口:
netstat -ano
- 查看指定端口:
netstat -ano|findstr "端口号"
- 查看指定端口号进程:
tasklist|findstr "端口号"
代码示例
package com.zlf.network;
import java.net.InetSocketAddress;
public class TestInetSocketAddress {
// 说到端口需要引入一个类:InetSocketAddress
// 此类实现IP套字节地址(IP+端口号)
/*
*构造方法
* ## 构造方法摘要
InetSocketAddress(InetAddress addr, int port)
根据IP地址和端口号创建套接字地址
InetSocketAddress(int port)
创建套接字地址,其中ip地址为通配符地址,端口号为指定值
InetSocketAddress(String hostname,int port)
根据主机名和端口号创建套接字地址
* */
public static void main(String[] args) {
InetSocketAddress localhost = new InetSocketAddress("localhost", 8080);
// 常用方法
System.out.println(localhost.getAddress());//获取InetAddress
System.out.println(localhost.getHostName());//获取域名
System.out.println(localhost.getPort());//获取端口
}
}
输出结果
localhost/127.0.0.1
localhost
8080
三、通信协议
TCP/IP的三次握手
- 第一次握手:客户端将标志位SYN置为1,随机产生一个值seq=J,并将改数据包发送给服务器端,客户端进入SYN_SENT状态等待服务器确认
- 第二次握手:服务器收到数据包后,由标志位SYN=1指导客户端请求建立连接,服务器将标志位SYN和ACK都置为1,ack=J+!,随机产生一个值seq=K,并将该数据包发送给客户端以确认连接请求,服务器进入SYN_REVD状态
- 第三次握手:客户端收到消息后,检查ack是否为J+1,ACK是否为1,如果正确将标志位ACK置为1,ack=k+1,并将该数据包发送给服务端,服务器检查ack是否为 K+1,ACK是否为1,如果正确建立连接,两端进入ESTABLISH状态,完成三次握手,随后两端开始传输数据
四次挥手(中断连接端可以是客户端,也可以是服务器端。) - 第一次挥手:客户端发送一个FIN=M,用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1状态。意思是说:“我客户端没有数据要发给你了,但是如果你服务器还有数据没有完成发送,则不必着急关闭连接,可以继续发送数据”
- 第二次挥手:服务器收到FIN后 ,发送ack=M+1,告诉客户端,你的请求我已经收到了,但是我还没准备好,请你继续等待我的消息,这个时候客户端进入FIN_WAIT_2状态,继续等待服务器的FIN报文
- 第三次挥手:当服务器确定数据已经完成发送,则向客户端发送FIN=N报文,告诉客户端,好了,我这边数据发完了,准备好关闭连接,服务器进入LAST_ACK状态。
- 第四次挥手:客户端收到FIN=N报文,就知道可以关闭连接了,但是他还是不相信网络,怕服务器不知道要关闭,所以发送ack=N+1后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。服务器收到ACK后,就知道可以断开连接了,客户端等待了2MSL后依然没有收到回复,则证明服务器端已经正常关闭了,最终客户端完成关闭
四、TCP通信
-
在java中,提供了两个类用于实现TCP通信程序
- 客户端:
java.net.Socket
类表示,创建socket对象,向服务端发出连接请求,服务端响应请求,两者建立连接开始通信 - 服务端:
java.net.ServerSocket
类表示,创建ServerSocket
对象,相当于开启了一个服务,并等待客户端得连接
- 客户端:
-
客户端代码实现
package com.zlf.network;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
//客户端
public class TCPClientDemo01 {
/*
* `Socket`类:该类试下了客户端得套接字
构造方法摘要
+ public Socket(String host,int port):创建套接字对象并将其连接到指定主机上的指定端口号。如果指定的host是null ,则相当于指定地址为回送地址。
回送地址(127.x.x.x) 是本机回送地址(Loopback Address),主要用于网络软件测试以及本地机进程间通信,无论什么程序,一旦使用回送地址发送数据,立即返回,不进行任何网络传输。
常用方法摘要
+ public InputStream getInputStream():返回此套接字得输入流
1. 如果此Socket具有相关联得通道,则生成InputStream得所有操作也关联该通道
2. 关闭生成得InputStream也将关闭相关得Socket
+ public OutputStream getOutputStream():返回此套接字得输出流
1. 如果此Scoket具有相关联的通道,则生成的OutputStream 的所有操作也关联该通道。
2. 关闭生成的OutputStream也将关闭相关的Socket。
+ public void close():关闭此套接字
1. 一旦一个socket被关闭,它不可再使用
2. 关闭此socket也将关闭相关得InputStream和OutputStream
+ public void shutdownOutput():禁用此套接字得输出流
1. 任何先前写出得数据将被发送,随后终止输出流*/
public static void main(String[] args) {
Socket socket = null;
OutputStream os = null;
try {
InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
socket = new Socket(inetAddress,8090);
os = socket.getOutputStream();
os.write("你好,我是客户端".getBytes());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- 服务端代码实现
package com.zlf.network;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
//服务端
public class TCPServerDemo01 {
/*
* 分析服务端内容
* 1. 需要一个地址*/
public static void main(String[] args) {
ServerSocket serverSocket = null;
InputStream is = null;
Socket socket = null;
ByteArrayOutputStream baos = null;
try {
serverSocket = new ServerSocket(8090);
socket = serverSocket.accept();
is = socket.getInputStream();
baos = new ByteArrayOutputStream();
int len = 0;
byte[] bytes = new byte[1024];
while((len=is.read(bytes))!=-1){
baos.write(bytes,0,len);
}
System.out.println("收到了来自客户端得"+socket.getInetAddress().getHostName()+"的消息"+baos.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
if(serverSocket!=null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(baos!=null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
五、UDP网络编程
从技术意义上来讲,只有TCP才会分Server和Client。对于UDP来说,从严格意义上来讲,并没有所谓的Server和Client。
java.net包给我们提供了两个类DatagramSocket(此类表示用于发送和接收数据报的套接字)和DatagramPacket(该类表示数据报的数据包。 )
发送数据端
package com.zlf.network;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class UDPClient {
public static void main(String[] args) throws Exception {
// 建立一个Socket
DatagramSocket datagramSocket = new DatagramSocket();
// 建一个包
String msg = "你好啊,服务器,UDP发送";
// 发送给谁
InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
int port = 9090;
DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,inetAddress,port);
// 发送包
datagramSocket.send(packet);
// 关闭流
datagramSocket.close();
}
}
接收数据端
package com.zlf.network;
import java.io.ByteArrayOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPServer {
public static void main(String[] args) throws Exception{
// 开放端口
DatagramSocket socket = new DatagramSocket(9090);
byte[] buffer = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(buffer,0,buffer.length);
// 接收数据包
socket.receive(datagramPacket);
System.out.println(datagramPacket.getAddress().getHostName());
System.out.println(new String(datagramPacket.getData(),0,datagramPacket.getLength()));
// 关闭连接
socket.close();
}
}
六、UDP实现消息传输
发送方
package com.zlf.network.chat;
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 Send {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String data = bufferedReader.readLine();
System.out.println(data);
while(true){
DatagramPacket packet = new DatagramPacket(data.getBytes(),0,data.getBytes().length, InetAddress.getByName("127.0.0.1"),8000);
socket.send(packet);
data = bufferedReader.readLine();
}
}
}
接收方
package com.zlf.network.chat;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Receive {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(8000);
while (true) {
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
socket.receive(packet);
String receiveDta = new String(packet.getData(),0, packet.getLength());
System.out.println(receiveDta);
}
}
}
七、URL下载网络资源
java.net包下
构造方法摘要
URL(String spec)
根据String表示形式创建URL对象。URL(String protocol,String host,int port,String file)
根据指定协议名,主机名,端口号和文件名创建URL对象URL(String protocol,String host,String file)
根据指定的协议名、主机名、和文件名创建URL
常用方法
String getProtocol()
获取此URL的协议名称String getHost()
获取URL的主机名String getPort()
获取此url的端口号String getPath()
获取此 URL 的文件路径。String getFile()
获取此 URL 的文件名。String getQuery()
获取此 URL的查询部分。URLConnection openConnection()
返回一个URLConnection实例,表示与URL引用的远程对象的URL 。URLConnection
类中又有一个方法:
InputStream getInputStream()
返回从此打开的连接读取的输入流。
代码示例
package com.zlf.network.URL;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class TestURL {
/*
* 常用方法
+ String getProtocol() 获取此URL的协议名称
+ String getHost() 获取URL的主机名
+ String getPort() 获取此url的端口号
+ String getPath() 获取此 URL 的文件路径。
+ String getFile()获取此 URL 的文件名。
+ String getQuery()获取此 URL的查询部分。
+ URLConnection openConnection() 返回一个URLConnection实例,表示与URL引用的远程对象的URL 。
+ URLConnection类中又有一个方法:
InputStream getInputStream() 返回从此打开的连接读取的输入流。
* */
public static void main(String[] args) throws IOException {
URL url = new URL("http://localhost:8080/zhoulinfeng/%E7%BA%BF%E6%9D%A1.jpg");
System.out.println(url.getProtocol());
System.out.println(url.getHost());
System.out.println(url.getHost());
System.out.println(url.getPort());
System.out.println(url.getPath());
System.out.println(url.getFile());
System.out.println(url.getQuery());
System.out.println("+++++++++++++++++++++++++");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
FileOutputStream fops = new FileOutputStream(new File("C:\\Users\\18317\\Desktop\\线条.jpg"));
byte[] buffer = new byte[1024];
int len;
while((len=inputStream.read(buffer))!=-1){
fops.write(buffer,0,len);
}
httpURLConnection.disconnect();
inputStream.close();
fops.close();
}
}