- 浏览: 21000 次
- 性别:
- 来自: 北京
最新评论
纸上得来终觉浅,绝知此事要躬行。—陆游
意思是说,从书本上得来的知识终归是浅薄的,要透彻的认知事务还必须亲自实践。
这句话告诉我们,除了要掌握好理论知识,还必须得亲自动手做实践,来证明结论。理论引导实践,实践推翻理论。正是这个道理!
前面三章,我们对Socket编程进行了一个比较全面的阐述,相信大家对Socket编程有了一个比较全面的认识,今天我们来实现一个实例,加深对Socket编程的理解。
1、实例:实现一个质数判断程序。即
客户端在控制台输入一个数字,服务端告诉客户端该数字是否是质数。
1)服务端程序流程:
(1)获取客户端输入的数据
(2)做判断处理
(3)返回处理结果
2)客户端程序流程:
(1)用户在控制台输入数字
(2)获取用户输入的数字并发送给服务端
(3)获取服务端响应结果,并输出在控制台中
3)说明:
(1)质数(素数):除了1和本身,没有其他公约数
(2)为节省流量,服务端程序不直接告诉客户端结果,而是通过规定的协议,返回状态码。
协议规定为(这个协议自己任意定):0 是质数, 1 不是质数, 2 输入非法
2、代码实现:
1)服务端代码:
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 服务端:判断客户端输入的数字是否是质数 * 步骤: * 1.获取客户端输入的数据 * 2.做判断处理 * 3.返回处理结果 * * @author Sam * */ public class PrimeNumServer { // 服务端监听的端口号 private static final int PORT = 10000; /** * @param args */ public static void main(String[] args) { try { ServerSocket ss = new ServerSocket(PORT); System.out.println("Server 等待客户端接入..."); while (true) { // 监听客户端请求 Socket socket = ss.accept(); // 监听到有客户端接入,则开启一个子线程处理请求 new Thread(new Task(socket)).start(); } } catch (IOException e) { e.printStackTrace(); } } /** * 处理Socket请求任务类 * */ private static class Task implements Runnable { private Socket socket; private BufferedReader buffRreader; private BufferedWriter buffWriter; public Task(Socket socket) { try { this.socket = socket; // 字符读取流 this.buffRreader = new BufferedReader( new InputStreamReader(socket.getInputStream())); // 字符写入流 this.buffWriter = new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { handlRequest(); } /** * 处理请求 */ private void handlRequest() { try { // 接收客户端数据 String data = receive(); // 处理逻辑 String result = checkIsPrimeNum(data); // 发送响应结果 send(result); } finally { StreamUtils.close(buffRreader, buffWriter); close(socket); } } /** * 检查是否是质数,根据协议规定,返回状态码 * @param numStr * @return 0 是质数, 1 不是质数, 2 输入非法 */ private String checkIsPrimeNum(String numStr) { // 先判断输入的是否是数字 boolean isNumber = isNumber(numStr); // 是数字,进一步判断是否是质数(素数) if (isNumber) { int number = Integer.parseInt(numStr); return isPrimeNumber(number); } else {// 输入非数字,则认为是非法的 return "2"; } } /** * 判断是否是数字 * @param numStr * @return */ private boolean isNumber(String numStr) { Pattern pattern = Pattern.compile("[0-9]*"); Matcher matcher = pattern.matcher(numStr); return matcher.matches(); } /** * 判断是否是质数 * @param number * @return 0 是质数, 1 不是质数, 2 输入非法 */ private String isPrimeNumber(int number) { if (number < 2) {// 如果数字小于2,则认为是非法 return "2"; } else { // 真正做质数的判断逻辑 for (int i=2; i<=number-1; i++) { /* * 用2至number-1之间的所有数去整除number, * 如果有一个能被整除,说明是number非质数 */ if (number % i == 0) { return "1"; } } return "0"; } } /** * 接收客户端发送过来的数据 * @return */ private String receive() { try { return buffRreader.readLine(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 向客户端发送响应结果 * @param result */ private void send(String result) { try { buffWriter.write(result); buffWriter.newLine();// 写一个换行符 buffWriter.flush(); } catch (IOException e) { e.printStackTrace(); } } } /** * 关闭客户端Socket * @param socket */ private static void close(Socket socket) { if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } socket = null; } } }
服务端代码分析:
1、在isNumber(String numStr)方法中判断一个字符串是否是数字,用了一个正则匹配,匹配规则为:字符串是由0~9之间的数组成,并且可以出现零次或多次;有关更详细的匹配规则可以参看JDK文档中的:java.util.regex.Pattern类
2、在isPrimeNumber(int number)方法中判断一个数是否是质数:
用2至number-1之间的所有数去整除number,
1)如果有一个能被整除说明是number非质数;
2)如果所有的数都不未来整除,则说明是质数。
3、为了避免代码冗余,在finally子句中使用了一个StreamUtils流工具类来关闭资源,最后会把这个工具类的代码贴上。
2)客户端代码:
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.Socket; /** * 客户端:输入一个数字 * 步骤: * 1.用户在控制台输入数字 * 2.获取用户输入的数字并发送给服务端 * 3.获取服务端响应结果 * * @author Sam * */ public class PrimeNumClient { // 主机 private static final String HOST = "127.0.0.1"; // 端口号 private static final int PORT = 10000; private static Socket socket; private static BufferedReader buffReader; private static BufferedWriter buffWriter; private static BufferedReader keyboardReader; /** * @param args */ public static void main(String[] args) { try { init(); System.out.println("请在下面输入质数:"); // 获取键盘输入流 keyboardReader = new BufferedReader(new InputStreamReader(System.in)); // 发送数据 send(keyboardReader.readLine()); // 接收响应结果 String result = receive(); // 处理结果 handleResult(result); } catch (IOException e) { e.printStackTrace(); } finally {// 释放资源 StreamUtils.close(buffReader, buffWriter); StreamUtils.close(keyboardReader); close(socket); } } /** * 初始化操作 */ private static void init() { try { // 连接到指定的主机与端口号的服务器上 socket = new Socket(HOST, PORT); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); buffReader = new BufferedReader(new InputStreamReader(in)); buffWriter = new BufferedWriter(new OutputStreamWriter(out)); } catch (IOException e) { e.printStackTrace(); } } /** * 向服务端发送数据 * @param data */ private static void send(String data) { try { buffWriter.write(data); buffWriter.newLine();// 写一个换行符 buffWriter.flush(); } catch (IOException e) { e.printStackTrace(); } } /** * 接收服务端响应结果 * @return */ private static String receive() { try { return buffReader.readLine(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 处理服务端返回的结果 */ private static void handleResult(String result) { if ("0".equals(result)) {// 是质数 System.out.println("您输入的是质数"); } else if ("1".equals(result)) {// 不是质数 System.out.println("您输入的不是质数"); } else if ("2".equals(result)) { // 输入非法 System.out.println("警告!您输入非法!"); } } /** * 关闭客户端Socket * @param socket */ private static void close(Socket socket) { if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } socket = null; } } }
客户端代码分析:
1、获取用户输入的数据,往服务端写数据时,一定要记得用newLine()方法写一个换行符,否则服务端一直处于读取状态,不会停止,因为读不到结束符;同理,服务端在往客户端写入响应结果时,也要用newLine()方法写一个换行符,否则客户端也会一直处于阻塞状态;
2、获取服务端返回的响应结果,根据之前规定的协议,在控制台中输出相应的提示信息。
3)IO流工具类StreamUtils代码:
import java.io.IOException; import java.io.Reader; import java.io.Writer; /** * IO流工具 * @author Sam * */ public class StreamUtils { /** * 同时关闭字符读取流与字符写入流 * @param reader * @param writer */ public static void close(Reader reader, Writer writer) { close(reader); close(writer); } /** * 关闭字符读取流 * @param reader */ public static void close(Reader reader) { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } reader = null;// 置空 } } /** * 关闭字符写入流 * @param writer */ public static void close(Writer writer) { if (writer != null) { try { writer.close(); } catch (IOException e) { e.printStackTrace(); } writer = null;// 置空 } } }
IO流工具类代码分析:
一般操作中,比较常用的,而且代码变动不大的,我们都会封装成一个工具类,以后直接使用,而不用重复的写。既避免代码冗余,又提高工作效率。
3、运行结果:
注意:先运行Server程序,再运行Client程序。为了测试结果,多次运行Client程序,并输入不同的数据,得到不同的提示信息。
1)Server程序控制台:
2)Client程序控制台
(1)运行第1次:
(2)运行第2次:
(3)运行第3次:
(4)运行第4次:
4、总结:
程序代码的逻辑并不复杂,但是基本做到了代码结构化。每个功能点都封装成一个方法,不同的业务放在不同的代码块中。这样以后要是某个模块出现了问题,就找相应的模块修改,而不被其他逻辑所干扰;实际开始中,也应该是这种思想。
发表评论
-
基于JDK1.6的HashMap底层实现与分析
2018-01-21 14:13 531最新仔细看了一遍JDK1.6 HashMap的源码,收获颇 ... -
Java 中的值传递和引用传递
2016-06-08 20:44 657严格上讲,Java中只存 ... -
Java中的IO流-IO流体系介绍
2014-05-23 17:57 1302工欲善其事,必先利其器。—《论语》 意思是说,工匠要想做好他 ... -
Java中的File类操作
2014-05-22 17:46 1428业精于勤,荒于嬉;行 ... -
Java中的Socket编程(3)-深入
2014-04-16 14:23 743读不在三更五鼓,功只 ... -
Java中的Socket编程(2)-提高
2014-04-11 14:28 897日日行,不怕千万里; ... -
Java中的Socket编程(1)-入门
2014-04-10 14:10 665不积跬步,无以至千里! 意思是说不一小步一小步的积累,无法到 ... -
Java中两种比较器的实现
2014-04-08 15:40 3157先举例说明: 例一:如果要对一组数字进行排序,可以写一个排序 ... -
Java排序算法实现
2014-04-04 17:20 895温故而知新,可以为师矣! 经常温故旧的知识,每次都有新的体会 ...
相关推荐
本教程将深入探讨Java中的Socket编程,特别是如何实现网上广播功能。网上广播允许一个设备向网络上的所有设备发送数据,无需预先知道接收者的具体地址。 首先,让我们了解什么是Socket。Socket在计算机网络中是一种...
Socket编程是一种基础的网络通信机制,允许两个应用程序通过网络交换数据。 首先,让我们深入了解一下Java中的Socket。在Java中,Socket是`java.net.Socket`类的一个实例,它代表了TCP协议中的一个连接。创建Socket...
学习这些Java Socket编程实例,有助于理解TCP/IP通信的基本原理,为构建实际的网络应用程序打下坚实的基础。你可以通过调试和修改`SocketTest`代码,进一步探索和实践Socket编程的不同场景,如文件传输、聊天应用等...
#### 三、Java中的Socket编程实例 接下来,我们通过一个简单的Java Socket编程示例来深入了解如何在Java中实现Socket编程。该示例展示了一个简单的Web客户端程序,用于获取一个HTML页面的内容。 ```java import ...
在Java中,`java.net.Socket`和`java.net.ServerSocket`类是Socket编程的主要工具。 1. **Socket类**: - `Socket`类代表TCP连接的一端,用于建立客户端与服务器之间的连接。它的构造函数通常需要指定服务器的IP...
在Java中,Socket编程主要涉及两个关键类:`ServerSocket`和`Socket`。`ServerSocket`类用于服务器端,它监听指定端口的连接请求。创建一个`ServerSocket`实例,例如`ServerSocket server = new ServerSocket(9998);...
Java Socket编程是网络编程的基础,它提供了在两个应用程序之间建立通信连接的能力。在这个场景中,我们讨论的是如何使用Java的Socket来实现文件上传功能,即从客户端将文件发送到服务器,然后保存到服务器的数据库...
Java Socket编程是Java平台中用于实现网络通信的核心API,它基于TCP/IP协议栈,提供了低级别的、面向连接的、可靠的字节流通信。在本文中,我们将深入探讨Java Socket编程的关键概念、工作原理以及如何创建服务端和...
在Java中,Socket编程是实现网络通信的基础,它提供了进程间通信的能力,使得两个相隔万里的计算机可以通过互联网进行数据交换。本篇文章将深入讲解如何通过三步学习Java Socket编程。 **第一步:理解Socket** ...
本文将通过一个具体的Java Socket编程实例来深入探讨如何使用Java实现客户端与服务端之间的通信。 #### 二、基础知识概述 在开始具体实例之前,我们需要了解一些基本概念: - **Socket**:Socket是一种用于在网络...
在Java中,Socket API提供了丰富的类库支持,使得开发人员能够轻松实现网络编程。 - **客户端Socket**:用于发起连接请求,与服务端建立连接。 - **服务端Socket**:用于监听客户端的连接请求,并接收或发送数据。 ...
这个简单的Java Socket编程实例展示了如何使用Java的网络API来实现客户端和服务器之间的通信。在实际应用中,可能会涉及到更复杂的逻辑,如解析HTTP请求,处理多线程并发连接,以及数据的编码和解码等。在压缩包文件...
在深入理解JAVA_SOCKET编程技术之前,我们首先需要明确Socket的基本概念及其在Java中的应用。Socket,即套接字,是网络通信的基础,它提供了一种在网络中进行数据交换的方式,使不同计算机上的进程能够通过TCP/IP...
在Java面试中,对Socket编程的理解和应用能力通常是评估开发者技能的重要标准。以下是对Socket编程的详细阐述: 1. **Java Socket编程基础** - Java中的Socket是网络通信的基础,它提供了两台计算机之间低级别的...
Java Socket编程是网络编程中的重要组成部分,主要用于实现客户端与服务器之间的通信。在Java中,Socket是基于TCP协议的,提供了一种可靠的、基于字节流的双向通信方式。本资料包含的"Java源码:Socket编程"是一个...
本实例代码是为了配合博客文章,提供一个简单的Java Socket聊天室的实现,帮助读者更好地理解和应用Socket编程。 在Java Socket编程中,主要有两个核心概念:服务器端(Server)和客户端(Client)。服务器端通过...
Java网络socket编程是Java编程语言在网络编程中的一项核心技术,主要涉及到网络通信的两个基本概念:客户端(Client)和服务器(Server)。在Java中实现网络通信,主要依赖于Socket编程模型,尤其是基于TCP/IP协议的...
8. **网络编程**:Java的Socket编程允许创建客户端和服务器应用程序,实现网络通信。理解TCP和UDP协议,以及套接字的使用,能让你构建网络应用。 9. **数据库操作**:JDBC(Java Database Connectivity)是连接Java...
《Java TCP/IP Socket编程》(原书第2版)是一本深入探讨Java中Socket编程的专著,旨在帮助读者理解并掌握如何在Java环境中利用TCP/IP协议进行网络通信。本书不仅详细介绍了Socket的工作原理,还提供了丰富的示例...
在Java编程领域,网络编程是不可或缺的一部分,而Socket通信则是实现网络数据传输的基础。本案例主要探讨了如何使用Java的Socket API进行简单的文件传输。在这个过程中,我们将涉及到以下几个关键知识点: 1. **...