概述
网络编程从大的方面说就是对信息的发送到接收,中间传输为物理线路的作用。
网络编程最主要的工作就是在发送端把信息通过规定好的协议进行组装包,在接收端按照规定好的协议把包进行解析,从而提取出对应的信息,达到通信的目的。
网络编程最主要的目的就是进行数据的交换、通信。
网络通信的要素
进行网络通信的时候,我们需要知道通信双方的主机的地址,即需要知道IP以及端口号。
同时,在进行网络通信的时候,通信双方必须遵循相同的通信协议才可以进行通信。
IP、端口
IP
IP 是唯一定位了网络上的一台计算机,在Java中有关IP的类是InetAddress,该类表示 Internet Protocol version 4 (IPv4) 地址。
public final class Inet4Address
extends InetAddress
IP地址为127.0.0.1,表示的是本机地址即localhost
public class TestIP {
public static void main(String[] args) {
try {
// 查询本机IP地址
InetAddress address = InetAddress.getByName("127.0.0.1");
InetAddress address1 = InetAddress.getByName("localhost");
InetAddress address2 = InetAddress.getLocalHost();
System.out.println(address);
System.out.println(address1);
System.out.println(address2);
System.out.println(address.getAddress());
System.out.println(address.getCanonicalHostName());
System.out.println(address.getHostAddress());
System.out.println(address.getHostName());
// 查询网站的IP地址
InetAddress address3 = InetAddress.getByName("www.csdn.net");
System.out.println(address3);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
端口
端口是用来表示计算机上的一个程序的进程。
- 不同的进程有不同的端口号,是用来区分软件的。
- 端口号规定的范围是0~65535。
- 不同的协议中的端口号可以相同,但是同一个协议下,端口号不能相同,否则会冲突。
端口分类
- 公有端口:0~1023
- 程序注册端口:1024~49151, 分配用户或者程序
- 动态、私有:49152~ 65535
端口号 | 协议 |
---|---|
21 | FTP(文件传输服务) |
22 | SSH( 远程连接服务) |
23 | Telent(终端仿真服务) |
25 | SMTP(简单邮件传输服务) |
53 | DNS(域名解析服务) |
80 | HTTP(超文本传输服务) |
443 | HTTPS(加密的超文本传输服务) |
1521 | Oracle数据库 |
3306 | MYSQL数据库 |
5432 | postgresql数据库 |
6379 | Redis数据库 |
8080 | TCP服务端默认端口 |
8888 | Nginx服务器 |
9200 | Elasticsearch服务器 |
27017 | mongoDB数据库 |
22122 | fastdfs服务器 |
可以使用如下命令查看端口
netstat -ano #查看所有的端口
netstat -ano|findstr "5900" # 查看指定的端口
tasklist|findstr "8696" #查看指定端口的进程
InetSocketAddress类
public class InetSocketAddress
extends SocketAddress
InetSocketAddress类实现 IP 套接字地址(IP 地址 + 端口号)。它还可以是一个对(主机名 + 端口号),在此情况下,将尝试解析主机名。
public class TestPort {
public static void main(String[] args) {
try {
InetSocketAddress address = new InetSocketAddress("127.0.0.1",8080);
InetSocketAddress address1 = new InetSocketAddress("localhost",8080);
System.out.println(address);
System.out.println(address1);
System.out.println(address.getAddress());
System.out.println(address.getHostName());
System.out.println(address.getHostString());
System.out.println(address.getPort());
} catch (Exception e) {
e.printStackTrace();
}
}
}
通信协议
有关通信协议,我们最常听到的就是TCP/IP协议,这是一个协议簇。
这里我们主要使用的是TCP和UDP协议。
TCP是需要建立连接的,是稳定的。
通信双方使用TCP协议进行通信的时候需要:
- 先建立连接
- 再进行数据传输
- 最后释放连接
UDP是不需要建立连接的,是不稳定的。
TCP
public class Socket
extends Object
Socket类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。
public class ServerSocket
extends Object
ServerSocket类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。
消息传输
客户端:
public class TestClient {
public static void main(String[] args) {
Socket socket = null;
OutputStream os =null;
try {
// 1. 需要知道服务器的地址和端口号
InetAddress address = InetAddress.getByName("127.0.0.1");
int port=8080;
// 2. 创建一个socket连接
socket = new Socket(address,port);
// 3. 发送消息 使用IO流
os = socket.getOutputStream();
os.write("欢迎学习Java".getBytes());
} catch (Exception e) {
e.printStackTrace();
}finally {
if (os!=null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
服务端:
public class TestServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket =null;
InputStream is =null;
ByteArrayOutputStream bos =null;
try {
// 1. 建立socket连接
serverSocket = new ServerSocket(8080);
// 2. 等待客户端连接过来
socket = serverSocket.accept();
// 3. 接收消息 使用IO流
is = socket.getInputStream();
// 4. 使用IO流读取消息
bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len=is.read(buffer))!=-1){
bos.write(buffer,0,len);
}
System.out.println(bos.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
if (bos!=null){
try {
bos.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();
}
}
}
}
}
UDP
public class DatagramSocket
extends Object
DatagramSocket 类表示用来发送和接收数据报包的套接字。
public final class DatagramPacket
extends Object
DatagramPacket 类表示数据报包。数据报包用来实现无连接包投递服务。
消息传输
客户端:
public class TestClient01 {
public static void main(String[] args) {
try {
// 1. 建立一个socket
DatagramSocket socket = new DatagramSocket();
// 2. 建立一个包
String s = "信息传输...";
InetAddress address = InetAddress.getByName("localhost");
int port =9000;
// 数据
DatagramPacket packet = new DatagramPacket(s.getBytes(), 0, s.getBytes().length,address,port);
// 3. 发送包
socket.send(packet);
// 4. 关闭流
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
服务端:
public class TestServer01 {
public static void main(String[] args) {
try {
// 开放端口
DatagramSocket socket = new DatagramSocket(9000);
// 接收数据包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
// 阻塞接收
socket.receive(packet);
System.out.println(packet.getAddress().getHostAddress());
System.out.println(new String(packet.getData(),0,packet.getLength()));
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
URL
public final class URL
extends Object
implements Serializable
URL类代表一个统一资源定位符,它是指向互联网“资源”的指针,用于定位资源的、定位互联网上的一个资源。
URL的格式:
协议://ip地址:端口/项目名/资源
public class TestURL {
public static void main(String[] args) {
try {
URL url = new URL("//http://localhost:8080/ll/SecurityFile.txt");
// 获取端口号
System.out.println(url.getPort());
// 获取文件
System.out.println(url.getFile());
// 获取主机IP
System.out.println(url.getHost());
// 获取协议
System.out.println(url.getProtocol());
// 获取参数
System.out.println(url.getQuery());
// 获取全路径
System.out.println(url.getPath());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}