- 网络编程的目的?
- 直接或间接的通过网络协议与其他计算机实现数据交换、进行通讯
- 网络编程的两个主要问题
- 如何准确的定位网络上的一台或多台主机 :定位主机上特定的应用
- 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 {
// 创建服务端SocketserverSocket = 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编程案例一* 客户端发送数据到服务端 服务端将接收到的数据显示在控制台* 自定义客户端*/@Testvoid 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通信编程案例一* 自定义服务器端* 接收客户端消息 并写出到控制台*/@Testvoid 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 {/*** 发送端*/@Testvoid 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();}}}/*** 接收端*/@Testvoid 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();// 将字节转换成StringString 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();}}}}
