Java SE学习之【网络编程JavaSocket】
一、网络基础了解
1、网络架构模型
网络架构模型主要有OSI参考模型和TCP/IP五层模型
- OSI定义了网络互连的七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层、应用层)
- TCP/IP五层协议(物理层、数据链路层、网络层、传输层、应用层)
2、IP地址
IP,全称互联网协议地址,是指IP地址,意思是分配给用户上网使用的网际协议(英语:InternetProtocol,IP)的设备的数字标签。
通俗的:为实现网络中不同计算机之间的通信,每台机器都必须有一个唯一的标识—IP地址
IP地址格式:数字型,如:192.168.1.1
3、端口
- 用于区分不同应用程序
- 端口号范围为0 ~ 65535,其中0 ~ 1023为系统所保留
- IP地址和端口号组成了所谓的Socket,Socket是网络上运行的程序之间双向通信链路的终结点,是TCP和UDP的基础
- http:80 ftp:21 telnet:23
二、Java中的网络相关API
1、InetAddress类
InetAddress类用于标识网络上的硬件资源,表示互联网协议(IP)地址。
下面是JDK文档中InetAddress类的方法:
下面通过代码进一步了解方法的使用:
package com.socket;import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;/*** InetAddress类的应用* @author 87366**/
public class InetAddressDemo {public static void main(String[] args) throws UnknownHostException {InetAddress address = InetAddress.getLocalHost();System.out.println("计算机名:" + address.getHostName());System.out.println("IP地址:" + address.getHostAddress());byte[] bytes = address.getAddress(); //获取字节数组的IP地址System.out.println("字节数组的形式的IP:" + Arrays.toString(bytes));System.out.println(address);//直接输出InetAddress对象//根据机器名获取InetAddress实例//InetAddress address2 = InetAddress.getByName("DESKTOP-KF6VQOG");InetAddress address2 = InetAddress.getByName("111.114.38.225");System.out.println("计算机名:" + address2.getHostName());System.out.println("IP地址:" + address2.getHostAddress());}}
2、URL
URL(Uniform Resource Locator)统一资源定位符,表示Internet上某一资源的地址
下面直接上代码理解URL的常用方法:
package com.socket;import java.net.MalformedURLException;
import java.net.URL;/*** URL常用方法* @author 87366**/
public class URLDemo {public static void main(String[] args) {try {//创建一个URL实例URL imooc = new URL("https://www.imooc.com");//?后面表示参数 #后面表示锚点URL url = new URL(imooc,"/index.html?username=tom#test");System.out.println("协议:" + url.getProtocol());System.out.println("主机:" + url.getHost());//如果未指定端口号,则使用默认的端口号,此时getPort()方法返回值为-1System.out.println("端口:" + url.getPort());System.out.println("文件路径:" + url.getPath());System.out.println("文件名:" + url.getFile());System.out.println("相对路径:" + url.getRef());System.out.println("查询字符串::" + url.getQuery());} catch (MalformedURLException e) {e.printStackTrace();}}}
3、使用URL读取网页内容
- 通过URL对象的openStream()方法可以得到指定资源的输入流
- 通过输入流可以读取、访问网络上的数据
通过下面代码实现:
package com.socket;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;/*** 使用URL读取页面内容* @author 87366**/
public class URLDemo1 {public static void main(String[] args) {InputStream inpStr = null;InputStreamReader inpStream = null;BufferedReader bufffedReader = null;try {//创建一个URL实例URL url = new URL("https://www.baidu.com");//通过URL的openStream方法获取URL对象所表示的资源的字节输入流inpStr = url.openStream();//将字节输入流转换为字符输入流inpStream = new InputStreamReader(inpStr , "utf-8");//为字符输入流添加缓冲bufffedReader = new BufferedReader(inpStream);String dataString = bufffedReader.readLine();//读取数据while (dataString != null) {System.out.println(dataString);dataString = bufffedReader.readLine();}} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally {try {bufffedReader.close();inpStream.close();inpStr.close();} catch (IOException e) {e.printStackTrace();}}}}
三、通过Socket实现TCP编程
1、Socket通信
TCP协议是面向连接、可靠的、有序的,以字节流的方式发送数据
- 基于TCP协议实现网络通信的类
- 客户端的Socket类
- 服务器端的ServerSocket类
2、Socket通信实现步骤
- 创建ServerSocket和Socket
- 打开连接到Socket的输入/输出流
- 按照协议对Socket进行读/写操作
- 关闭输入输出流、关闭Socket
3、编程实现基于Socket通信的用户登录功能
- 服务器端
- 创建ServerSocket对象,绑定监听端口
- 通过accept()方法监听客户端请求
- 连接建立后,通过输入流读取客户端发送的请求信息
- 通过输出流向客户端发送相应信息
代码实现:
package com.socket;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;/*** 基于TCP协议的Socket通信,实现用户登录* 服务器端* @author 87366**/
public class ServerDemo {//加入多线程public static void main(String[] args) {ServerSocket serverSocket = null;Socket socket = null;try {//1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口serverSocket = new ServerSocket(8888);//记录客户端的数量int count = 0;System.out.println("***服务器即将启动,等待客户端的连接***");//循环监听等待客户端的连接while(true) {//调用accept()方法开始监听,等待客户端的连接socket = serverSocket.accept();//创建一个新的线程ServerThreadDemo serverThreadDemo = new ServerThreadDemo(socket);//启动线程serverThreadDemo.start();count++;//统计客户端的数量System.out.println("客户端的数量:" + count);InetAddress address = socket.getInetAddress();System.out.println("客户端" + count + "的IP地址:" + address.getHostAddress());}} catch (IOException e) {e.printStackTrace();}finally {try {//5.关闭相关资源socket.close();serverSocket.close();} catch (IOException e) {e.printStackTrace();} }}//第一个版本public static void main1(String[] args) {ServerSocket serverSocket = null;Socket socket = null;InputStream inputStream = null;InputStreamReader inputStreamReader = null;BufferedReader bufferedReader = null;OutputStream outputStream = null;PrintWriter printWriter = null;try {//1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口serverSocket = new ServerSocket(8888);//2.调用accept()方法开始监听,等待客户端的连接System.out.println("***服务器即将启动,等待客户端的连接***");socket = serverSocket.accept();//3.获取输入流用来读取客户端信息inputStream = socket.getInputStream();inputStreamReader = new InputStreamReader(inputStream);bufferedReader = new BufferedReader(inputStreamReader);String infor = null;while ((infor = bufferedReader.readLine()) != null) {//循环读取客户端的信息System.out.println("我是服务器,客户端说:" + infor);}socket.shutdownInput();//4.获取输入流,响应客户端的请求outputStream = socket.getOutputStream();printWriter = new PrintWriter(outputStream);printWriter.write("欢迎您!");printWriter.flush();} catch (IOException e) {e.printStackTrace();}finally {try {//5.关闭相关资源printWriter.close();outputStream.close();bufferedReader.close();inputStreamReader.close();inputStream.close();socket.close();serverSocket.close();} catch (IOException e) {e.printStackTrace();} }}
}
package com.socket;
/*** 服务器端线程处理类* @author 87366**/import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;public class ServerThreadDemo extends Thread {//和本线程相关的SocketSocket socket = null;public ServerThreadDemo(Socket socket) {this.socket = socket;}//线程执行的操作,响应客户端的请求@Overridepublic void run() {InputStream inputStream = null;InputStreamReader inputStreamReader = null;BufferedReader bufferedReader = null;OutputStream outputStream = null;PrintWriter printWriter = null;try {//获取输入流用来读取客户端信息inputStream = socket.getInputStream();inputStreamReader = new InputStreamReader(inputStream);bufferedReader = new BufferedReader(inputStreamReader);String infor = null;while ((infor = bufferedReader.readLine()) != null) {//循环读取客户端的信息System.out.println("我是服务器,客户端说:" + infor);}socket.shutdownInput();//获取输入流,响应客户端的请求outputStream = socket.getOutputStream();printWriter = new PrintWriter(outputStream);printWriter.write("欢迎您!");printWriter.flush();} catch (IOException e) {e.printStackTrace();}finally {try {//5.关闭相关资源printWriter.close();outputStream.close();bufferedReader.close();inputStreamReader.close();inputStream.close();} catch (IOException e) {e.printStackTrace();} }}
}
上面的代码包含了两个版本,第一个版本是没有加入多线程的,第二个加入了多线程更加高效。
- 客户端:
- 创建Socket对象,指明需要连接的服务器的地址和端口号
- 连接建立后,通过输出流向服务器端发送请求信息
- 通过输入流获取服务器响应的信息
- 关闭相关资源
代码实现:
package com.socket;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;/*** 客户端* @author 87366**/
public class ClientDemo {public static void main(String[] args) { Socket socket = null;OutputStream outputStream = null;PrintWriter printWriter = null;BufferedReader bufferedReader = null;InputStream inputStream = null;try {//1.创建客户端Socket,指定服务器端口和地址socket = new Socket("localhost",8888);//2.获取输出流,向服务器发送消息outputStream = socket.getOutputStream();printWriter = new PrintWriter(outputStream);printWriter.write("用户名:tom;密码:456");printWriter.flush();socket.shutdownOutput();//3.获取输入流,用来读取服务器端的响应信息inputStream = socket.getInputStream();bufferedReader = new BufferedReader(new InputStreamReader(inputStream));String infor = null;while ((infor = bufferedReader.readLine()) != null) {//循环读取客户端的信息System.out.println("我是客户端,服务端说:" + infor);}} catch (IOException e) {e.printStackTrace();}finally { try {//4.关闭相关资源bufferedReader.close();inputStream.close(); printWriter.close();outputStream.close();socket.close();} catch (IOException e) {e.printStackTrace();}}}
}
运行时,先运行服务器端代码,再运行客户端代码
四、通过Socket实现UDP编程
1、DatagramPacket
UDP编程
- UDP协议(用户数据报协议)是无连接的、不可靠的、无序的
- UDP协议以数据报作为数据传输的载体
- 进行数据传输时,首先需要将要传输的数据定义成数据报(Datagram),在数据报中指明数据所要达到的Socket(主机地址和端口号),然后再将数据报发送出去
2、相关操作类
- DatagramPacket:表示数据包报
- DatagramSocket:进行端到端通信的类
3、编程实现基于Socket通信的用户登录功能
- 服务器端
- 创建DatagramSocket,指定端口号
- 创建DatagramPacket
- 接收客户端发送的数据信息
- 读取数据
代码实现:
package com.socket;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;/*** 服务器端,实现基于UDP的用户登录* @author 87366**/
public class UDPServerDemo {public static void main(String[] args) throws IOException {/** 接收客户端发送的数据*///1.创建服务器端DatagramSocket,指定端口DatagramSocket socket = new DatagramSocket(8889);//2.创建数据报,用于接收客户端发送的数据byte[] data = new byte[1024];//创建字节数组,指定接收的数据包的大小DatagramPacket packet = new DatagramPacket(data, data.length);//3.接收客户端发送的数据System.out.println("****服务器端已经启动,等待客户端发送数据****");socket.receive(packet);//此方法在接收到数据报之前会一直阻塞//4.读取数据String infor = new String(data, 0, packet.getLength());System.out.println("我是服务器,客户端说:" + infor);/** 向客户端响应数据*///1.定义客户端的地址、端口号、数据InetAddress address = packet.getAddress();int port = packet.getPort();byte[] data2 = "欢迎您!".getBytes();//2.创建数据报,包含响应的数据信息DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);//3.响应客户端socket.send(packet2);socket.close();}
}
- 客户端实现步骤
- 定义发送信息
- 创建DatagramPacket,包含将要发送的信息
- 创建DatagramSocket
- 发送数据
代码实现:
package com.socket;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;/*** 客户端* @author 87366**/
public class UDPClient {public static void main(String[] args) throws IOException {/** 向服务器端发送数据*///1.定义服务器的地址、端口号、数据InetAddress address = InetAddress.getByName("localhost");int port = 8889;byte[] data = "用户名:admin;密码:123".getBytes();//2.创建数据报,包含发送的数据信息DatagramPacket packet = new DatagramPacket(data, data.length, address, port);//3.创建DatagramSocket对象DatagramSocket socket = new DatagramSocket();//4.向服务器端发送数据报socket.send(packet); /** 接收服务器端响应的数据*///1.创建数据报,用于接收服务器端响应的数据byte[] data2 = new byte[1024];DatagramPacket packet2 = new DatagramPacket(data2, data2.length);//2.接收服务器响应的数据socket.receive(packet2);//3.读取数据String reply = new String(data2, 0, packet2.getLength());System.out.println("我是客户端,服务器说:" + reply);//4.关闭资源socket.close(); }
}
Java SE学习之【网络编程JavaSocket】相关推荐
- JAVA SE 学习之网络开篇
目录 1.什么是计算机网络? 2.什么是网络传输协议? 3.网络协议的分层 4.数据的封装与解封 5. ip地址 6.端口 7.URL 8.Socket 9. UDP协议 10. TCP协议 11.T ...
- Java并发编程实战_阿里P9整理分享的亿级流量Java高并发与网络编程实战PDF
前言 为了帮助初级开发者快速掌握高并发.网络编程.微服务.海量数据的处理这些实用技术,本文以"理论+范例"的形式对各个知识点进行了详细的讲解,力争让读者在实践中快速掌握相关知识. ...
- 阿里P9整理分享的亿级流量Java高并发与网络编程实战PDF
前言 有人调侃我们说: 程序员不如送外卖.送外卖是搬运食物,自己是搬运代码,都不产出新的东西-- 透支体力,又消耗健康,可替代性极强,30岁之后就要面临被优化的危险-- 想跳槽,但是更高的平台难进,同 ...
- 第一阶段Java SE学习概述
Java SE学习概述 Java SE 学习分为五个阶段 第一部分:基础程序设计: 第二部分:面现象对象编程: 第三部分:Java SE 高级应用: 第四部分:JavaSE 新特性: 第五部分:MyS ...
- 20165310 Java实验五《网络编程与安全》
20165310 Java实验五<网络编程与安全> 任务一 题目:①编写MyBC.java实现中缀表达式转后缀表达式的功能:②编写MyDC.java实现从上面功能中获取的表达式中实现后缀表 ...
- python网络编程要学吗_总算发现如何学习python网络编程
为了提高模块加载的速度,每个模块都会在__pycache__文件夹中放置该模块的预编译模块,命名为module.version.pyc,version是模块的预编译版本编码,一般都包含Python的版 ...
- Java面试知识点:网络编程
问题:Java面试知识点:网络编程 答案: 1.InetAddress 代码如下: package com.xy;import java.net.InetAddress; import java.ne ...
- Java语言进阶:网络编程入门
Java语言进阶:网络编程 网络编程入门 C/S C/S结构 :全称为Client/Server结构,是指客户端和服务器结构.常见程序有QQ.迅雷等软件. 特点: 客户端和服务器是分开的,需要下载客户 ...
- 《亿级流量JAVA高并发与网络编程实战》笔记--------更新中
<亿级流量JAVA高并发与网络编程实战>笔记 第一章 高并发概述 "高并发技术" 是一个广义的概念,是指一种高效的地实现并发需求的解决方案,是技术领域的名称,可以包含架 ...
- linux java socket编程_深入学习socket网络编程,以java语言为例
了解java的socket编程与Linux Socket API之间的关系 一.java的网络编程 1.socket原理 socket通信就是通过IP和端口号将两台主机建立连接,提供通信.主机A的应用 ...
最新文章
- android studio 自动提示jni代码,如何将JNI(C/C++本机代码)添加到现有的Android Studio项目中...
- Sagit.Framework For IOS 开发框架入门教程6:网络请求STHttp
- 今天小暑是什么时间_小暑适合发朋友圈的说说 小暑吐槽天气热的搞笑幽默说说...
- Ubuntu与 Fedora之对比
- 最全面的MySQL笔记
- 数学和物理太难?这些动图让你秒懂抽象概念
- post修改服务器数据源,postgresql安装及配置超详细教程
- php中goto另一个页面,php中goto操作符的详细介绍
- Python重复字符串并使用指定分隔符进行连接
- matlab 中的元组(cell)
- 阵列信号处理——研究背景与现状
- Tomcat日志配置,可结合log4j
- KEILC51的下载和安装与工程建立
- 倪海厦天纪笔记16_倪海厦-天纪16
- ipad端网页屏幕变小了
- 绘王两款便携数位屏同时发售,全贴合防眩光屏配硬笔
- 公司技术分享-全文技术分享Lucene VS ElasticSearch VS Solr
- Python简笔画——用Turtle库画一只《穿红靴子的小鸭》
- 打开PDF文件时,出现“打开本文档时发生错误。无法找到本文件。”解决办法,亲自尝试成功
- c#中的反射的高级语法_Kubernetes第3部分中的seccomp新语法以及一些高级主题