Java编程基础之网络编程

网络编程

文章目录

    • 网络编程
      • 概述
        • C/S和B/S
        • 网络通信协议
        • 网络编程要素
      • IP类
      • UDP协议数据传输
        • 发送端
        • 接收端
        • udp数据传输丢失问题
      • TCP概述
        • Socket客户端
        • ServerSocket服务端Socket
          • **服务器代码**
          • 客户端代码
        • 文件上传实现
          • 客户端
          • 服务端
          • 多线程版

概述

C/S和B/S

image-20210807101225599

网络通信协议

协议:protocol

网络通信协议市要求双方传递数据的计算机必须遵守的,按照对应的网络传输协议,才可以进入数据的交互和传递

常见协议:

  • UDP

    面向无连接,不可靠数据传输存在丢包

    传输速度快

    没有客户端和服务器区别,都可以作为发送端和接收端

    使用场景:直播,网络游戏

  • TCP/IP

    面向连接

    可靠数据传输,稳定

    有明确服务器和客户端概念

    使用场景:数据下载,文件传输

网络编程要素

  1. 协议

    两个计算机之间数据传输,需要对应的协议来完成

  2. IP地址

    Internet Protocol Address

    当前计算机在网络中的一个地址编号,类似于手机号码

    IP地址有IPv4和IPv6两种格式

  3. 端口号

    端口号是当前应用程序在计算机中的一个编号,是计算机明确,当前的数据是给予哪一个程序使用,或者数据从哪一个程序发出

    端口号是一个short类型数据,范围0-65535

    0-1024属于特定的系统端口号,不能自定义使用

IP类

InetAddress

常用方法:

  • InetAddress getLocalhost();

    获取本机IP地址类对象

  • InetAddress getByName(String str);

    根据指定的主机名获取对应的IP地址对象

  • InetAddress[] getAllByName(String str);

    获取指定主机名,或者域名对应的所有IP地址类对象

package cn.ocean888;import java.net.InetAddress;
import java.net.UnknownHostException;public class Demo1 {public static void main(String[] args) throws UnknownHostException {InetAddress localHost = InetAddress.getLocalHost();System.out.println(localHost);InetAddress byNameAddress = InetAddress.getByName("秦的机械革命");System.out.println(byNameAddress);InetAddress byNameAddress2 = InetAddress.getByName("www.ocean888.cn");System.out.println(byNameAddress2);InetAddress[] byNameAddress3 = InetAddress.getAllByName("www.baidu.com");for (InetAddress inetAddress : byNameAddress3) {System.out.println(inetAddress);}}
}

image-20210807135618348

UDP协议数据传输

用户数据报协议:User Datagram Protocol

数据传递采用数据包方式传递,所有的数据要进行打包操作,并且没有对应的客户端服务器概念,有且只有发送端和接收端

Socket 套接字

数据在需要进行传递操作时,在数据传递的两台计算机当中必须有对应的Socket,这里采用UDP协议,则必须有一个UDP协议的Socket

DatagramSocket();创建一个发送端UDP协议Socket对象DatagramSocket(int port);创建一个接收端UDP协议的Socket对象,这里需要监听指定端口     

数据包的打包方法

发送端数据打包方式

DatagramPacket DatagramPacket(byte[] buf, int length, InetAddress address, int port);/* 	buf:需要传递数据的字节数组length:当前字节数组中数据容量字节数address:接收端IP地址对象port:接收端对应的端口号
*/

接收端数据接收方式

需要准备一个空的数据包
DatagramPacket DatagramPacket(byte[] buf, int length);/*buf:字节缓冲数组,通常是1024的整数倍length:当前字节缓冲数组的容量
*/	

发送端

步骤:

  1. 创建UDP服务器对应的发送端Socket
  2. 准备对应的数据包,需要带有指定数据
  3. 发送数据 send
  4. 发送 udp 发送端
package cn.ocean888;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class SenderDemo1 {public static void main(String[] args) throws IOException {System.out.println("udp发送端");// 创建对应的SocketDatagramSocket socket = new DatagramSocket();// 准备数据包byte[] bytes = "ocean".getBytes();DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 8848);// 发送数据包socket.send(packet);// 关闭udp发送端socket.close();}
}

接收端

步骤:

  1. 打开UDP服务,监听指定端口
  2. 创建新的空数据包
  3. 通过Socket接受数据 receive
  4. 关闭 UDP 接收端
package cn.ocean888;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;public class ReceiveDemo1 {public static void main(String[] args) throws IOException{System.out.println("接收端启动");// 创建socket监听端口DatagramSocket socket = new DatagramSocket(8848);// 准备空数据包byte[] buf = new byte[1024];DatagramPacket packet = new DatagramPacket(buf, buf.length);// 接收数据socket.receive(packet);// 确定接受到的字节长度int length = packet.getLength();System.out.println(new String(buf, 0, length));// 关闭socketsocket.close();}
}

需要先启动接收端,监听端口

image-20210807150815719

udp数据传输丢失问题

  1. 网络不好,传输不稳定,带宽不够,数据包丢失
  2. 电脑性能问题

TCP概述

TCP是相对于UDP比较稳定的传输协议,存在三次握手,保证连接状态,同时明确区分客户端和服务端之分

TCP服务中需要服务器端先启动,需要监听指定端口,等待客户端连接

TCP操作:Java中提供了两个Socket

  1. 服务端Socket

    java.net.ServerSocket;

    创建对应的ServerSocket开启服务器,等待客户端连接

  2. 客户端Socket

    java.net.Socket

    创建客户端Socket,并且连接服务器,同时将Socket发送给服务器绑定注册

tcp 三次握手四次挥手流程图

img

Socket客户端

给客户端提供的数据传输符合TCP/IP要求的Socket对象

构造方法Constructor
Socket(String host, int port);host是服务器IP地址,port对应服务器程序的端口号成员方法Method
InputStream getInputStream();获取Socket对象输入字节流,可以从服务器获取对应的数据InputStream是一个资源,需要在程序退出时关闭OutputStream getOutputStream();获取Socket对象输出字节流,可以发送数据到服务器OutputStream是一个资源,需要在程序退出时关闭void close();关闭客户端Socketvoid shutdownOutput();禁止当前Socket发送数据TCP/IP协议对应的Socket是给予IO流实现的        

ServerSocket服务端Socket

在服务器开启Socket服务器

构造方法 ConstructorServerSocket(int port);开启ServerSocket服务器,并且明确服务端口成员方法 Method:Socket accept();监听并且连接,得到一个Socket对象,同时该方法是一个阻塞方法,会始终处于一个监听状态返回的是Socket,即客户端Socket对象,获取到当前Socket对象,相当于获取到客户端连接,同时使用Socket和客户端一致

TCP客户端服务端输入输出关系

TCP客户端服务端输入输出关系

服务器代码

流程:

  1. 创建ServerSocket服务器,同时监听指定端口
  2. 通过accept方法获取Socket连接,得到客户端Socket对象
  3. 通过Socket对象,获取InputStream,读取客户端发送数据
  4. 通过Socket对象,获取OutputStream,发送数据给客户端
  5. 关闭服务
package cn.ocean888_tcp;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class ServerDemo {public static void main(String[] args) throws IOException {System.out.println("服务端启动");// 1.创建ServerSocket服务器,同时监听指定端口ServerSocket serverSocket = new ServerSocket(8888);// 2.通过accept方法获取Socket连接,得到客户端Socket对象Socket socket = serverSocket.accept();// 3.通过Socket对象,获取InputStream,读取客户端发送的数据InputStream inputStream = socket.getInputStream();// IO流操作byte[] buf = new byte[1024];int length = inputStream.read(buf);System.out.println(new String(buf, 0, length));// 4.通过Socket对象,获取OutputStream,发送数据给客户端OutputStream outputStream = socket.getOutputStream();String str = "ocean";outputStream.write(str.getBytes());// 5.关闭Socket服务同时关闭当前Socket使用的输入字节流和输出字节流// Closing this socket will also close the socket's InputStream and OutputStreamsocket.close();}
}
客户端代码

流程:

  1. 创建Socket服务,同时明确连接服务器的IP地址和对应端口号
  2. 通过Socket对象,获取对应的OutputStream,发送数据给服务器
  3. 通过Socket对象,获取对应的InputStream,接收服务器发送数据
  4. 关闭连接
package cn.ocean888_tcp;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;public class ClientDemo {public static void main(String[] args) throws UnknownHostException, IOException {System.out.println("客户端启动");// 1.创建Socket服务,同时明确连接服务器的IP地址和对应端口号Socket socket = new Socket("169.254.252.105", 8888);// 2.通过Socket对象,获取对应的OutputStream对象,发送数据给服务器OutputStream outputStream = socket.getOutputStream();outputStream.write("client connect".getBytes());// 3.通过Socket对象,获取对应的InputStream对象,接收服务器发送数据InputStream inputStream = socket.getInputStream();byte[] buf = new byte[1024];int length = inputStream.read(buf);System.out.println(new String(buf, 0, length));// 4.关闭服务socket.close();}
}

需要首先启动服务端

image-20210808085436695

image-20210808085444677

文件上传实现

文件上传细节图例

客户端

流程:

  1. 创建对应的文件输入字节流操作,可以使用缓存
  2. 启动Socket
  3. 获取Socket输出OutputStream对象,发送数据给服务器
  4. 边读边发
  5. 文件读取结束,发送完毕,关闭客户端
package cn.ocean888_tcp;import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;public class FileClient {@SuppressWarnings("resource")public static void main(String[] args) throws IOException {// 1.创建缓冲流BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(new File("D:\\JavaCode\\test\\test.jpg")));// 2.创建socketSocket socket = new Socket(InetAddress.getLocalHost(), 8848);// 3.获取socket输出流OutputStream outputStream = socket.getOutputStream();int length = -1;byte[] buf = new byte[1024 * 8];// 4.读取数据,发送输出,边读边发while ((length = bufferedInputStream.read(buf)) != -1) {outputStream.write(buf, 0, length);}// 5.关闭连接socket.close();}
}
服务端

流程:

  1. 开启服务端,创建ServerSocket服务
  2. 明确文件保存位置,创建对应文件夹的输出缓冲字节流
  3. 读取数据,写入文件
  4. 关闭服务端
package cn.ocean888_tcp;import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;public class FileServer {public static void main(String[] args) throws IOException {// 1.开启服务端,创建ServerSocket对象ServerSocket serverSocket = new ServerSocket(8848);Socket socket = serverSocket.accept();// 2.明确保存文件位置,创建对应文件夹缓冲字节流BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("D:\\JavaCode\\test\\copy.jpg")));// 3.获取Socket对应的输入流InputStream inputStream = socket.getInputStream();// 4.边读边写int length = -1;byte[] buf = new byte[1024 * 8];while((length = inputStream.read(buf)) != -1) {bos.write(buf, 0, length);}// 5.关闭资源bos.close();socket.close();}
}

运行后

image-20210808103738633

多线程版

解决单线程代码问题:

  1. 保存的文件名是一致的,无法保存多个文件

    使用uuid解决

  2. 服务器代码需要执行多个功能在结束

  3. 服务端代码不可能只有一个上传文件功能

    使用多线程

package cn.ocean888_tcp;import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class TcpGoodServer {public static void main(String[] args) throws IOException {System.out.println("服务器代码启动");// 1.启动TCP服务端服务ServerSocket serverSocket = new ServerSocket(8848);// 2.使用线程池ExecutorService tp = Executors.newFixedThreadPool(5);// 3.循环while (true) {// 连接客户端Socket socket = serverSocket.accept();tp.submit(() -> {try {System.out.println(Thread.currentThread().getName());InputStream inputStream = socket.getInputStream();String fileName = UUID.randomUUID().toString();BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("D:\\JavaCode\\test\\" + fileName + ".jpg")));int length = -1;byte[] buf = new byte[1024 * 8];while ((length = inputStream.read(buf)) != -1) {bos.write(buf, 0, length);}bos.close();socket.close();} catch (IOException e) {e.printStackTrace();}});}}
}

运行:先启动服务端在启动多个客户端

image-20210808143807372

image-20210808143843725

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/252785.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Java 基础

Java 基础知识点整理 Java 语言是一种优秀的编程语言,由 C 语言、C 语言发展而来。Java 语言提供了一些有效的新特性,使得使用 Java 比 C 更容易写出“无错代码”。 Java特性和优点 面向对象编程的思想,更简单有效,Java 省略了 …

第二章Java编程基础

一、填空题 1.Java程序代码必须放在一个类中,类使用class关键词定义。 2.Java中的注释有三类,分别是单行注释、多行注释、文档注释。 3.Java语言中,int类型所占存储空间为4个字节。 4.用于比…

Java编程基础②

Java编程基础 Java中的注释Java中的标识符Java中的关键字Java中的常量常量类型定义常量 java中的变量变量的定义及其数据类型变量的类型转换变量的作用域 java运算符算术运算符赋值运算符比较运算符逻辑运算符位运算符运算符的优先级 java流程控制语句if条件语句switch条件语句…

【JAVA】1.编程基础

1.Java基本语法 JAVA基本格式: 修饰符 class 类名{ 程序代码 } public class java {public static void main(String[] args) {System.out.println("HelloWorld"); } public static void main(String[] args) {} (对于初学者来说这个部分必…

第二章 Java编程基础

第二章 Java编程基础 目录 一. Java基本语法1. 基本格式2. 注释3. 标识符4. 关键字5. 常量 二. 变量1. 定义2. 数据类型3. 整数类型变量4. 浮点类型变量5. 字符类型变量6. 布尔类型变量7. 类型转换8. 自动提升9. 变量作用域 三. 运算符1. 算数…

Java基础 —— 编程入门

一、比特(bit)和字节(byte) 一个0或者一个1存储为一个比特(bit),是计算机中最小的存储单位。计算机中是最基本的存储单元是字节(byte)。 每个字节由8个比特构成。 计算机就是一系列的电路开关。每个开关存在两种状态:关(off)和开(on)。如果电路是开的,它…

5.Java编程基础

📋 个人简介 💖 作者简介:大家好,我是W_chuanqi,一个编程爱好者 📙 个人主页:W_chaunqi 😀 支持我:点赞👍收藏⭐️留言📝 💬 愿你我共…

Java编程基础知识(一)

目录 一.Java的基本语法 1.Java的基本语法格式 2.Java中的注释 3.Java中的关键字 Java中的标识符 二.Java中的常量与变量 1.常量 2.变量 三.Java中的运算符 四.数据输入 一.Java的基本语法 1.Java的基本语法格式 编写Java程序必须先声明一个类,然后再类中…

第二章:JAVA编程基础

目录 一:Java的基本语法格式 二:Java中的变量与常量 三:Java中的运算符 四:选择结构语句 五:循环结构语句 六:数组 一:Java的基本语法格式 1:语法格式 [修饰符] class 类名{…

Java入门必备知识

目录 一、前言 二、HelloWord案例编写 三、基础语法 1.快速生成语句:(IDEA编辑器下) 2.注释: 3.标识符 标识符: 标识符的组成: 标识符的组成规则: 4.标识符命名约定: 小驼峰…

【Java基础知识 1】Java入门级概述,让阿里架构师告诉你为什么要分库分表

1998年12月8日,第二代Java平台的企业版J2EE发布。 1999年4月27日,HotSpot虚拟机发布。 2005年6月,在Java One大会上,Sun公司发布了Java SE 6。此时,Java的各种版本已经更名,已取消其中的数字2&#xff0c…

Java编程基础

目录 第一篇、Java编程基础 ❀Java中的属性名词 ❀Java数据类型 ❀转义字符 ❀&& 和 & 与 || 和 | ❀方法 第二篇、Java面向对象编程 ❀类和对象 ❀面向过程和面向对象的区别 ❀面向对象程序设计的主要特性 ❀类和对象概述 ❀对象的内存结构 ❀垃圾空间…

【Java编程指南】语法基础

目录 一、前言 二、关键字 三、数据类型 1.存储单元 2.存储范围 3.类型转换 四、常量 五、变量 六、标识符 七、注释 一、前言 学习目标 1:熟悉Java的关键字、数据类型(包括范围)、常量与变量的区别 学习目标 2:类型转…

Java 学习(一)Java语言基础

Java 语言基础(一) 前言一、注释和标识符1. 注释2. 字符集3. 标识符4. 关键字(略) 二、数据类型1.基本类型2.引用类型 三、 常量和变量1.常量2.变量 四、操作符1.赋值运算符2.算术运算符3.关系运算符4.逻辑运算符5.位运算符6.三位运算符7.instanceof运算…

java编程基础(入门级)(超级完整版)

java基础编程(入门) 01基础知识 1.计算机基础 【1】进制 A.十进制转化二进制 除以2,求余数,商继续除以2,一直到0为止,从底下往上得到结果。 B.二进制转化十进制 1 | 1 | 0 | 0 2 3 ∣ 2 2 ∣ 2 1 ∣ 2 …

Ext JS 6 驾临

是的,Ext JS 6 就要来了! 统一一份代码 Ext JS 6 最大的改变,莫过于就是将 PC 端与移动端的代码统一起来,务求采用相同 API 来开发不同平台的客户端界面,这样无论桌面、平板和手机都是使用同一个 JavaScript 框架&…

extjs02

Ext.js 自定义事件和监听器 2022-05-20 17:11 更新 事件是在类发生的时候触发的。 例如,当一个按钮被点击或元素被渲染之前/之后。 写事件的方法: 内置事件使用侦听器附加事件监听自定义事件 内置事件使用侦听器 xt JS提供了用于在Ext JS文件中编写事件和自定…

Extjs6 --- 学习笔记(1)创建一个新项目

原公司使用的前端框架是Extjs,于是系统学习了Extjs的4和6。旧东家的项目主要为后台管理系统,因此对前端界面UI的要求并不高,侧重于数据的展示与处理 ,刚开始使用的是Extjs4,后升级成6。现在,把自己的学习过…

Extjs6 学习(一)

一 学习前的了解: 1.Extjs6其实是结合了两个框架:Extjs 和Sencha Touch; 2.Extjs6有两个工具包: classic (存放原来Extjs的可视化组件)和 modern (存放原来Sencha Touch的可视化组件); 3.你需要安装一个叫Sencha Cmd的工具, 这会让你的Extjs应用开发变得简单; 二 安装 1.下…

我的第一篇博客---ExtJs6安装

我的第一篇博客—ExtJs6安装 1、下载extjs6 GPL版和sencha cmd。 下载地址:http://pan.baidu.com/s/1qYGk2T2(百度云盘里面就有这两个) 官方下载地址: extjs6 GPL版:https://www.sencha.com/legal/gpl/ sencha cm…