网络编程
网络基础
网络通信
- 两台设备之间通过网络实现数据交互
- java.net包下提供了一系列类和接口,供程序员使用,完成网络通信
网络
- 概念:两台或多台设备通过一定物理设备连接起来构成了网络
- 根据网络覆盖的范围可以对网络进行划分:
- 局域网:覆盖范围较小,例如教室机房等
- 城域网:覆盖范围较大,例如一个城市
- 广域网:覆盖范围最大,可以覆盖全国甚至全球。例如万维网
网络通信协议
TCP/IP(Transmission Control Protocol/Internet Protocol)
中文译为传输控制协议/因特网互联协议,又叫网络通讯协议,这个协议是Internet最基本的协议,简单的说,就是由网络层的IP协议和传输层的TCP协议组成的
OSI模型 | TCP/IP模型 | TCP/IP模型各层对应的协议 |
---|---|---|
应用层 | 应用层 | http、ftp、telnet、DNS |
表示层 | ||
会话层 | ||
传输层 | 传输层 | TCP、UDP |
网络层 | 网络层 | IP、ICMP、ARP |
数据链路层 | 物理+数据链路层 | LINK |
物理层 |
TCP和UDP
TCP协议:传输控制协议
- 使用TCP协议前,必须先建立TCP连接,形成传输数据通道
- 传输前采用“三次握手”方式,是可靠的
- TCP协议进行通信的两个应用进程:客户端、服务端
- 在连接中可进行大数据量的传输
- 传输完毕需要进行已建立连接的释放,效率低
UDP协议:用户数据协议
- 将数据、源、目的封装成数据包,不需要建立连接
- 每个数据包的大小限制在64KB
- 因无需连接所以是不可靠的
- 发送数据结束时,不需要释放资源(因为不是面向连接的),速度快
InetAddress类
相关方法
- 获取InetAddress对象 getLocalHost
- 根据指定主机名/域名获取ip地址对象 getByName
- 获取InetAddress对象的主机名 getHostName
- 获取InetAddress对象的地址 getHostAddress
public class API_ {
public static void main(String[] args) throws UnknownHostException {
//获取本机的InetAddress对象
InetAddress localHost = InetAddress.getLocalHost();
//获取主机ip地址
String hostAddress = localHost.getHostAddress();
//获取主机名/域名
String hostName = localHost.getHostName();
System.out.println(localHost);
System.out.println("hostAddress:"+hostAddress);
System.out.println("hostName:"+hostName);
//根据名称获取主机信息
InetAddress host = InetAddress.getByName("DESKTOP-44L9PVB");
System.out.println(host);
//根据域名获取主机信息 www.baidu.com
InetAddress baidu = InetAddress.getByName("www.baidu.com");
System.out.println(baidu);//www.baidu.com/180.101.49.12
}
}
Socket
基本介绍
- 套接字(Socket)开发网络应用程序被广泛采用,以至于成为事实上的标准
- 通信的两端都要有socket,是两台机器间通信的端点
- 网络通信其实就是socket之间的通信
- socket允许程序把网络连接当成一个流,数据在两个socket之间进行IO传输
- 一般主动发起通信的应用程序是客户端,等待通信请求的是服务端
TCP编程
TCP网络通信编程
- 基于客户端-服务端的网络通信
- 底层使用的是TCP/IP协议
- 应用场景举例:客户端发送数据,服务端接收并打印在控制台
- 基于socket的TCP编程
- 当客户端连接到服务端后,实际上客户端也是通过一个端口和服务端进行通讯的,这个端口是TCP/IP来分配的
public class TCPFileCopyClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
String path = "g:\\桌面\\11111.png";
OutputStream outputStream = socket.getOutputStream();
//BufferedOutputStream bos = new BufferedOutputStream(outputStream);
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[8096];
int len ;
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));
while ((len = bis.read(bytes)) != -1) {
outputStream.write(bytes,0,len);
}
//写socket记得关闭
socket.shutdownOutput();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
String s = br.readLine();
System.out.println(s);
outputStream.close();
br.close();
socket.close();
}
}
public class TCPFileCopyServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9999);
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(inputStream);
String des = "JAVAImprove\\src\\testCopy.png";
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(des));
byte[] bytes = new byte[8096];
int len;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes,0,len);
}
OutputStream outputStream = socket.getOutputStream();
outputStream.write("收到图片".getBytes());
//如果用字符流需要进行flush刷新
socket.shutdownOutput();
bos.close();
socket.close();
serverSocket.close();
}
}
netstat命令
- netstat -an 可以查看当前主机网络情况,包括端口监听和网络连接情况
- netstat -an | more 可以分页显示 netstat -anb 显示程序信息
- 要求在dos控制台下执行
UDP编程
UDP网络通信编程(了解)
- 类DataGramSocket 和DatagramPacket实现了基于UDP协议网络程序
- UDP数据包通过数据包嵌套字DataGramSocket发送和接收,系统不保证UDP数据包一定能够安全送到目的地,也不能确定什么时候可以抵达
- DataGramPacket对象封装了UDP数据包,在数据包中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号
- UDP协议中每个数据包都给出了完整的地址信息,因此无需建立发送方和接收方的连接
基本流程
- 核心的两个类 DataGramSocket和DataGramPacket
- 建立发送端,接收端
- 建立数据包
- 调用DataGramSocket的发送、接收方法
- 关闭DataGramSocket
public class UDPReceiverA {
public static void main(String[] args) throws IOException {
//初始化udpsocket 监听9999端口
DatagramSocket socket = new DatagramSocket(9999);
//初始化DataGramPacket用于接收数据
byte[] data = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(data, data.length);
//等待数据 没有就阻塞
socket.receive(datagramPacket);
int length = datagramPacket.getLength();
byte[] bytes = datagramPacket.getData();
System.out.println(length);
System.out.println(new String(bytes));
byte[] callback = "好".getBytes();
datagramPacket = new DatagramPacket(callback,callback.length, InetAddress.getByName("127.0.0.1"),9998);
socket.send(datagramPacket);
socket.close();
}
}
public class UDPSenderB {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(9998);
byte[] bytes = "hi,明天出去玩".getBytes();
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("DESKTOP-44L9PVB"), 9999);
socket.send(datagramPacket);
datagramPacket = new DatagramPacket(new byte[1024],1024);
socket.receive(datagramPacket);
byte[] callback = datagramPacket.getData();
System.out.println(new String(callback));
socket.close();
}
}