网络基础
IP地址:用于区分网络上每一台主机。
网络协议:IPV4、IPV6。用于统一通信语言标准。
端口号:0~65535,(0~1023内定)用于区分计算机上的不同程序。
TCP/IP协议:应用最广的协议。TCP(传输控制协议),IP(互联网协议)
网络编程:程序通过网络进行连接。位于java.net包中
java.net 包中提供了两种常见的网络协议的支持:
- TCP:传输控制协议,保障了应用程序之间的可靠通信。常用于互联网协议,被称 TCP / IP
- UDP:用户数据报协议,一个无连接的协议。提供了应用程序之间要发送的数据的数据报
java网络编程中的四大类
- InetAddress:用于表示IP地址
- URL:读写网络资源
- Socket:实现网络通信(TCP)
- Datagram:保存数据报中,进行通信(UDP)
InetAddress类
常用方法
- static InetAddress getLocalHost() //返回本地主机实例
- static InetAddress getByAddress(byte[] addr) //输入ip地址,返回对应主机实例
- static InetAddress getByName(String host) //输入主机名,返回对应主机实例
- static InetAddress getByAddress(String host, byte[] addr) //输入主机名,ip地址,返回主机实例
- byte[] getAddress() //返回主机ip地址
- String getHostAddress() //返回主机地址
- String getHostName() //返回主机名
- boolean isAnyLocalAddress() //检查 InetAddress 是否是通配符地址的实用例行程序。
- boolean isLinkLocalAddress() //检查 InetAddress 是否是链接本地地址的实用例行程序。
- boolean isLoopbackAddress() //检查 InetAddress 是否是回送地址的实用例行程序。
URL
统一资源定位符:表示网络上资源,它是指向互联网“资源”的指针。
eg.:协议 : 资源名
https://www.baidu.com/index.html
构造方法:
- URL(String spec)
- URL(String protocol, String host, int port, String file)
- URL(String protocol, String host, int port, String file, URLStreamHandler handler)
- URL(String protocol, String host, String file)
- URL(URL context, String spec)
- URL(URL context, String spec, URLStreamHandler handler)
eg.:
URL test = new URL("http://www.baidu.com");
URL url = new URL(test,"/index.html?username=tom#test");// #后面表示锚点,?后面表示参数
常用方法:
- Object getContent() //获取此URL内容
- int getDefaultPort() //获取此URL默认端口
- int getPort() //获取此端口,没有指定则默认-1
- String getFile() // 获取此URL文件名
- String getHost() //获取主机名
- String getPath() //获取该路径
- String getProtocol() //获取此协议名
- String getQuery() //获取URL查询部分
- String getRef() //获取URL的锚点(引用),获取相对路径
- String getUserInfo() //获取URL的userInfo部分
- URLConnection openConnection() //URL 所引用的远程对象的连接。
- InputStream openStream() //打开此 URL连接,返回从该连接读入的 InputStream
- protected void set(String protocol, String host, int port, String file, String ref) //设置 URL 的字段
实例应用——获取网页信息
//获取网页信息
import java.io.*;
import java.net.*;
public class TestURL {
public static void main(String[] args) {
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
try {
URL url = new URL("http://www.baidu.com");
inputStream = url.openStream();//获取网页的字节流
inputStreamReader = new InputStreamReader(inputStream, "utf-8");//转化为字符流
bufferedReader = new BufferedReader(inputStreamReader);//提高读写效率
String data = bufferedReader.readLine();
while (data != null) {
System.out.println(data);
data = bufferedReader.readLine();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bufferedReader != null) {
bufferedReader.close();
}
if (inputStreamReader != null) {
inputStreamReader.close();
}
if (inputStream != null) {
inputStream.close();
}
} catch (Exception e) {
}
}
}
}
基于TCP的socket编程(有序,有连接,可靠)
套接字使用TCP提供了两台计算机之间的通信机制。
主要类有
- Socket:客户端
- ServerSocket:服务端
ServerSocket类
java.net.ServerSocket 类以获取一个端口,并且侦听客户端请求。
构造方法
- ServerSocket()//创建非绑定服务器套接字
- ServerSocket(int port) //创建绑定到特定端口的服务器套接字
- ServerSocket(int port, int backlog) //指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号
- ServerSocket(int port, int backlog, InetAddress address) //使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器
常用方法
- Socket accept()//侦听并接受到此套接字的连接
- void bind(SocketAddress endpoint) //将 ServerSocket 绑定到特定地址
- void bind(SocketAddress host, int backlog) //将 ServerSocket 绑定到特定地址
- int getLocalPort() //返回此套接字在其上侦听的端口
- boolean isBound() //返回 ServerSocket 的绑定状态
- boolean isClosed() //返回 ServerSocket 的关闭状态
- static void setSocketFactory(SocketImplFactory fac) //设置服务器套接字实现工厂
- void setSoTimeout(int timeout) //通过指定超时值启用/禁用 SO_TIMEOUT
Socket类
java.net.Socket 类代表客户端和服务器都用来互相沟通的套接字,套接字是两台机器间通信的端点。
关闭时,io流同时关闭。
构造方法
- Socket() //系统默认 SocketImpl 创建未连接套接字
- Socket(InetAddress host, int port)//创建套接字并连接到指定 IP 地址的指定端口号
- Socket(String host, int port) //连接到指定主机上的指定端口号
- Socket(Proxy proxy) //创建一个未连接的套接字并指定代理类型
- Socket(String host, int port, InetAddress localAddr, int localPort) //连接到指定远程主机上的指定远程端口
- Socket(InetAddress host, int port, InetAddress localAddr, int localPort) //连接到指定远程主机上的指定远程端口
常用方法
- void bind(SocketAddress bindpoint) //绑定到本地地址
- void connect(SocketAddress endpoint) //连接到服务器
- void connect(SocketAddress endpoint, int timeout) //连接到服务器,并指定一个超时值
- SocketChannel getChannel() //返回与此数据报关联的唯一 SocketChannel 对象
- InetAddress getInetAddress() //返回套接字连接的地址
- InputStream getInputStream() //返回此套接字的输入流
- OutputStream getOutputStream() //返回此套接字的输出流
- SocketAddress getRemoteSocketAddress() //返回此套接字连接的端点的地址
实例应用——单线程
//服务端
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//服务端
public class Server {
public static void main(String[] args) {
try {
//1.创建server实例并绑定端口
ServerSocket serverSocket = new ServerSocket(6666);
System.out.println("***服务端开始启动,等待客户端的连接***");
//2.调用accept(),监听客户端请求
Socket socket = serverSocket.accept();
//3.读取客户端请求信息
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String info = null;
while ((info = bufferedReader.readLine()) != null) {
System.out.println("客户端说:" + info);
}
socket.shutdownInput();
//4.输出服务端响应信息
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.write("欢迎使用!");
printWriter.flush();
//5.关闭相关资源
printWriter.close();
outputStream.close();
bufferedReader.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//客户端
import java.io.*;
import java.net.Socket;
//客户端
public class Client {
public static void main(String[] args) {
try {
//1.创建socket实例,并连接服务端
Socket socket = new Socket("localhost", 6666);
//2.建立连接后,发出请求
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.write("用户名:max ; 密码:123");
printWriter.flush();
socket.shutdownOutput();
//3.获取服务端响应信息
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String info = null;
while ((info = bufferedReader.readLine()) != null) {
System.out.println("服务端说:" + info);
}
//4.关闭相关资源
bufferedReader.close();
printWriter.close();
outputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
实例应用——多线程
//线程类
import java.io.*;
import java.net.Socket;
public class ServerThread extends Thread {
Socket socket = null;
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
BufferedReader bufferedReader = null;
OutputStream outputStream = null;
PrintWriter printWriter = null;
try {
//3.读取客户端请求信息
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String info = null;
while ((info = bufferedReader.readLine()) != null) {
System.out.println("客户端说:" + info);
}
socket.shutdownInput();
//4.输出服务端响应信息
outputStream = socket.getOutputStream();
printWriter = new PrintWriter(outputStream);
printWriter.write("欢迎使用!");
printWriter.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
//5.关闭相关资源
try {
if (printWriter != null)
printWriter.close();
if (outputStream != null)
outputStream.close();
if (bufferedReader != null)
bufferedReader.close();
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//服务端
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
try {
//1.创建server实例并绑定端口
ServerSocket serverSocket = new ServerSocket(6666);
//2.调用accept(),监听客户端请求
int count = 0;//客户端数量
System.out.println("***服务端开始启动,等待客户端的连接***");
//循环监听
while (true) {
Socket socket = serverSocket.accept();
ServerThread serverThread = new ServerThread(socket);
serverThread.start();
count++;
System.out.println("输出客户端连接的数量:"+count);
InetAddress address = socket.getInetAddress();
System.out.println("当前客户端ip:"+address);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
基于UDP的socket编程(无序、无连接、不可靠)
定义数据报Datagram,在数据报中指明数据要到达的socket(主机、端口),再发出。速度较快
主要类有:
- DatagramPacket:数据报包
- DatagramSocket:进行端对端通信
DatagramPacket类
数据报包用来实现无连接包投递服务。
每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。
从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。
构造方法
- DatagramPacket(byte[] buf, int length) //用来接收长度为 length 的数据包。
- DatagramPacket(byte[] buf, int length, InetAddress address, int port) //用来将长度为 length 的包发送到指定主机上的指定端口
- DatagramPacket(byte[] buf, int offset, int length) //构造 DatagramPacket,用来接收长度为 length 的包,在缓冲区中指定了偏移量
- DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) //将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号。
- DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) //将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号。
- DatagramPacket(byte[] buf, int length, SocketAddress address) //将长度为 length 的包发送到指定主机上的指定端口号。
常用方法
- InetAddress getAddress() //返回某台机器的 IP 地址
- byte[] getData() //返回数据缓冲区
- int getLength() //返回将要发送或接收到的数据的长度
- int getOffset() //返回将要发送或接收到的数据的偏移量
- SocketAddress getSocketAddress() //获取此数据报的远程主机的 SocketAddress
- void setAddress(InetAddress iaddr) 设置要将此数据报发往的那台机器的 IP 地址
- void setData(byte[] buf) //为此包设置数据缓冲区。
- void setData(byte[] buf, int offset, int length) //为此包设置数据缓冲区。
- void setLength(int length) //为此包设置长度。
- void setPort(int iport) //设置要将此数据报发往的远程主机上的端口号。
- void setSocketAddress(SocketAddress address) //设置远程主机的 SocketAddress
DatagramSocket类
数据报套接字是包投递服务的发送或接收点。每个在数据报套接字上发送或接收的包都是单独编址和路由的。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。
构造方法
- DatagramSocket() //绑定到本地主机上任何可用的端口
- DatagramSocket(DatagramSocketImpl impl) //指定 DatagramSocketImpl 未绑定数据报
- DatagramSocket(int port) //绑定到本地主机上的指定端口
- DatagramSocket(int port, InetAddress laddr) //绑定到指定的本地地址
- DatagramSocket(SocketAddress bindaddr) //绑定到指定的本地套接字地址
常用方法
- void bind(SocketAddress addr) //将此 DatagramSocket 绑定到特定的地址和端口
- void connect(InetAddress address, int port) //将套接字连接到此套接字的远程地址
- void connect(SocketAddress addr) //连接到远程套接字地址(IP 地址 + 端口号)
- void disconnect() //断开套接字的连接
- DatagramChannel getChannel() //返回关联DatagramChannel 对象(如果有)。
- InetAddress getInetAddress() //返回此套接字连接的地址。
- InetAddress getLocalAddress() //获取套接字绑定的本地地址。
- int getLocalPort() //返回此套接字绑定的本地主机上的端口号。
- SocketAddress getLocalSocketAddress() //绑定的端点的地址,未绑定则返回 null。
- int getPort() //返回此套接字的端口
- boolean isBound() //返回套接字的绑定状态。
- boolean isClosed() //返回是否关闭了套接字。
- boolean isConnected() //返回套接字的连接状态。
- void receive(DatagramPacket p) //从此套接字接收数据报包。
- void send(DatagramPacket p) //从此套接字发送数据报包。
- void setBroadcast(boolean on) //启用/禁用 SO_BROADCAST。
- static void setDatagramSocketImplFactory(DatagramSocketImplFactory fac) //设置工厂
实例应用——单线程
//服务端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPServer {
public static void main(String[] args) throws IOException {
//1.创建DatagramSocket,指定端口号
DatagramSocket socket = new DatagramSocket(6666);
System.out.println("————服务器已启动————");
byte[] data = new byte[1024];
//2.创建DatagramPacket
DatagramPacket packet = new DatagramPacket(data, data.length);
//3.接收客户端发送的数据信息
socket.receive(packet);
//4.读取数据信息
String info = new String(data, 0, packet.getLength());
System.out.println("这里是服务器,客户端说:" + info);
//5.定义发送信息
InetAddress address = packet.getAddress();
int port = packet.getPort();
byte[] data2 = "欢迎使用".getBytes();
//6.创建DatagramPakcet,包含要发送的信息
DatagramPacket packet1 = new DatagramPacket(data2,data2.length,address,port);
//7.发生数据
socket.send(packet1);
//8.关闭资源
socket.close();
}
}
//客户端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPClient {
public static void main(String[] args) throws IOException {
//1.定义发送信息
InetAddress address = InetAddress.getByName("localhost");
int port = 6666;
byte[] data = "max:123".getBytes();
//2.创建DatagramPacket,包含要发送的信息
DatagramPacket packet = new DatagramPacket(data,data.length,address,port);
//3.创建DatagramSocket
DatagramSocket socket = new DatagramSocket();
//4.发送数据
socket.send(packet);
byte[] data2 = new byte[1024];
//5.创建DatagramPacket
DatagramPacket packet1 = new DatagramPacket(data2,data2.length);
//6.接受客户端发送的数据信息
socket.receive(packet1);
//7.读取数据
String reply = new String(data2,0,packet1.getLength());
System.out.println("这里是客户端,服务器说:"+reply);
//8.关闭资源
socket.close();
}
}