- 网络编程的目的?
- 直接或间接的通过网络协议与其他计算机实现数据交换、进行通讯
- 网络编程的两个主要问题
- 如何准确的定位网络上的一台或多台主机 :定位主机上特定的应用
- ip确定网络上唯一的主机 对应Java类 InetAddress
- 端口号确定特定的应用
- 找到主机后 如何进行高效的可靠的数据传输
- 解: 通过网络通信协议
- 如何准确的定位网络上的一台或多台主机 :定位主机上特定的应用
- 网络通信协议
- 通信协议同层可以传递
- 上层可以调下层进行传递
- 不可以跃层传递
- TCP协议
- 采用TCP协议前 先创建TCP链接 形成数据传输通道
- 传输前 采用’三次握手’方式 建立点对点通信 是可靠的
- TCP协议的两个应用进程: 客户端、服务端
- 在链接中可进行大量的数据传输
- 传输完毕 释放已建立的链接 效率低
UDP协议
- 将数据、源、目的封装成数据包 不需要建立链接
- 每个数据报大小限制在64k内
- 发送不管对方是否准备好接收 接收方收到也不确认 不可靠的
- 可以广播发送
- 发送结束时无需释放资源 开销小 速度快
TCP网络编程示例
- Socket类 = ip+端口号 理解为客户端应用 通过他链接到服务器 实现数据传输、通信
- TCP示例 如客户端访问服务端
- 浏览器访问tomcat ```java **
@author:LYY 创建时间:2022/5/11 */ public class TCPTest {
/**
- TCP编程案例二
- 客户端发送文件到服务端 服务端接收保存并返回收到信息给客户端 客户端打印收到信息到控制台
自定义服务端 */ @Test void test04() throws IOException {
OutputStream outputStream = null; FileOutputStream fileOutputStream = null; InputStream inputStream = null; Socket socket = null; ServerSocket serverSocket = null; try {
// 创建服务端Socket
serverSocket = new ServerSocket(8999);
// 获取服务端链接
socket = serverSocket.accept();
// 获取输入流 获取客户端发送的文件
inputStream = socket.getInputStream();
// 获取输出流 保存客户端发送的文件到服务器(硬盘)
fileOutputStream = new FileOutputStream("美图.jpg");
byte[] bytes = new byte[1024];
// 记录每次读取的字节数量
int len;
while ((len = inputStream.read(bytes)) != -1) {
// 将文件流写到硬盘
fileOutputStream.write(bytes, 0, len);
}
// 返回客户端消息
outputStream = socket.getOutputStream();
outputStream.write("文件接收完成!".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket != null) {
serverSocket.close();
}
} }
/**
- TCP编程案例二
- 客户端发送文件到服务端 服务端接收保存并返回收到信息给客户端 客户端打印收到信息到控制台
自定义客户端 */ @Test void test03() { Socket socket = null; OutputStream outputStream = null; FileInputStream fileInputStream = null; try {
// 创建Socket对象
socket = new Socket(InetAddress.getByName("192.168.1.52"), 8999);
// 获取输入流 将要发送的文件转换为字节流
fileInputStream = new FileInputStream("preview.jpg");
// 获取输出流 发送文件
outputStream = socket.getOutputStream();
byte[] bytes = new byte[1024];
int read;
// 读文件的字节流
while ((read = fileInputStream.read(bytes)) != -1) {
// 发送文件
outputStream.write(bytes, 0, read);
}
// 告诉服务端 发送数据结束
socket.shutdownOutput();
// 获取输入流 准备获取服务端发送的消息
InputStream inputStream = socket.getInputStream();
bytes = new byte[1024];
// 记录每次读取的字节
int len;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
while ((len = inputStream.read(bytes))!=-1) {
byteArrayOutputStream.write(bytes,0,len);
}
System.out.println(byteArrayOutputStream.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }
/**
* TCP编程案例一
* 客户端发送数据到服务端 服务端将接收到的数据显示在控制台
* 自定义客户端
*/
@Test
void test01() {
OutputStream outputStream = null;
Socket socket = null;
try {
// 客户端TCP指向服务器端
socket = new Socket(InetAddress.getByName("192.168.1.52"), 8999);
// 获取输出流
outputStream = socket.getOutputStream();
// 将消息写出到服务器端
outputStream.write("我是客户端发送的消息!".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭输出流
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 关闭Socket(网通通信)
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* TCP通信编程案例一
* 自定义服务器端
* 接收客户端消息 并写出到控制台
*/
@Test
void test02() throws IOException {
ByteArrayOutputStream byteArrayOutputStream = null;
InputStream inputStream = null;
Socket accept = null;
ServerSocket serverSocket = null;
try {
// 创建服务器客户端
serverSocket = new ServerSocket(8999);
// 获取到客户端链接
accept = serverSocket.accept();
// 从客户获取到输入流 获取到客户端发送的内容
inputStream = accept.getInputStream();
// ByteArrayOutputStream 处理接收字节流输出字符串时容易出现乱码的问题
byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
// 记录每次读取到的字节数
int len;
// 读客户端发送的数据(字节流)
while ((len = inputStream.read(bytes)) != -1) {
byteArrayOutputStream.write(bytes, 0, len);
};
// toString方法调用ByteArrayOutputStream中的数组 并将数组中保存的所有字节(byte)创建成String返回
System.out.println(byteArrayOutputStream.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if (byteArrayOutputStream != null) {
try {
byteArrayOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (accept != null) {
try {
accept.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket != null) {
serverSocket.close();
}
}
}
}
7. UDP编程示例
```java
/**
* @author:LYY 创建时间:2022/5/11
* UDP编程示例
*/
public class UDPTest {
/**
* 发送端
*/
@Test
void seedTest() {
DatagramSocket datagramSocket = null;
try {
// UDP编程对象
datagramSocket = new DatagramSocket();
byte[] bytes = "测试信息!".getBytes();
// 数据打包对象
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length,InetAddress.getByName("127.0.0.1"),8999);
// 发送数据
datagramSocket.send(datagramPacket);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if (datagramSocket != null) {
datagramSocket.close();
}
}
}
/**
* 接收端
*/
@Test
void receiver() {
DatagramSocket datagramSocket = null;
try {
// UDP对象
datagramSocket = new DatagramSocket(8999);
// 定义接收字节数据的数组
byte[] bytes = new byte[64];
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
// 接收数据 数据保存到datagramPacket中
datagramSocket.receive(datagramPacket);
// 取出数据
byte[] data = datagramPacket.getData();
// 将字节转换成String
String s = new String(data, 0, datagramPacket.getLength());
System.out.println(s);
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (datagramSocket != null) {
datagramSocket.close();
}
}
}
}