- 浏览: 57193 次
- 性别:
- 来自: 河北
最新评论
使用 Java Socket 编程实现开放平台与 IBM 主机的文件传输
- 在网络世界中,网络中的节点间的信息的传递无疑是一个重要的环节。在 IBM 大型主机进入这个网络世界后,网络节点中的新成员又多了一种。要实现开放平台与 IBM 大型主机之间的数据通信其实并非难事,对于程序员而言,掌握一种实现模型和实现的接口就会使网络编程变得简单,易于实现。Java 的 JDK 就提供可一系列的 API 来完成网络编程。Socket 就是其中的一种。
- 本文的研究背景源于主机环境的 IMS 产品的 IMS Connect 组件的自动化测试的需求。该产品运行于主机环境,但是对于需要在开放平台进行自动化测试的工程师来说,数据的通信无疑是一个需要解决的问题。
- 本文首先会给出一些基本的概念,包括 Socket 编程、FTP 传输协议的基本概念及原理以及 Java 实现 Socket 编程的特点。然后将阐述 IMS Connect 项目面临的问题,即本文实现的背景环境。接着将给出这个背景下的解决方法和实现细节。然后以项目为背景应用及验证。最后本文会将该实现方法推广为通用的解决方法。
示例需要的环境:
- 需要在 Windows 上安装的软件:
- Rational Functional Tester V7.0
- 需要在 IBM z/OS 上安装的环境:
- IMS Version 9 (或者更新的版本)
- IMS Connect Version 9 (或者更新的版本)
- OTMA
- TCP/IP
在网络出现之前的单机系统时代,更多的是进程之间的通信。由于每个进程有自己的地址空间,为了保证两个进程的通信互不干扰又协调工作,操作系统提供了相应的设施。如 UNIX 系统中的管道(pipe)、命名管道(named pipe)和软中断信号(signal)。而在网络中,两个不同计算机中的进程需要通信首先要解决的是进程识别的问题。同一主机上,不同进程可以用进程号(process ID)作为唯一标识,但是在网络的环境里不同的主机上完全可以用同一进程号,所以这种方法来区别进程是不可行的。另外 , 操作系统支持的网络协议很多,不同的协议的工作方式是不一样的,包括网络的地址格式也不同。因此,还需要考虑不同网络协议的识别问题。
这个问题催生了 Socket。Socket 又称为“套接字”,用于描述网络地址与端口,它是一个通信的接口。它是应用层与 TCP/IP 协议族通信的中间的软件抽象层,它位于运输层和网际层之上,又位于应用层之下,作为一个抽象层存在。在设计模式中,可以把 Socket 的设计想象成“门面模式”。它把负责的 TCP/IP 协议族隐藏在 Socket 接口的后面,对用户而言,之需要找到 Socket,然后后面的事就让 Socket 的去组织。图 1 描述了 Socket 的作用和所处的位置。
FTP(File Transfer Protocol) 远程文件传输协议是众多应用层协议的一种。它工作在 OSI 模型的第七层,TCP 模型的第四层,即应用层。它是为了简化 IP 网络上系统之间文件传送的协议,所以与两台计算机所处的位置,连接的方式甚至是否使用同样的操作系统是无关的。这也正符合本文研究的开放平台与 IBM 主机环境传输文件的问题背景。
相比于 HTTP(HyperText Transfer Protocol,超文本传输协议),FTP 协议工作需要两个端口(HTTP 需要一个端口 80),一个端口是作为控制连接端口,也就是 21 端口,用于发送指令给服务器以及等待服务器响应;另一端口是 20(仅限于 PORT 模式),用于数据的传输,主要作用是从客户向服务器发送文件的。
下面给出了 Passive 模式和 Port 模式的示例图 :
图 2. Port 模式 端口示意图
图 3. Passive 模式 端口示意图
要想用 Java 来实现 Socket 这种客户机到服务器的模型,其实并非难事。Java 的 JDK 中有很多 API 帮助程序员来实现这个模型,这些 API 封装在 java.net 这个包里。正是由于这些 API 的存在,使用 Java 来创建您所在位置的 Server 十分简单。
ServerSocket server=new ServerSocket(1234); |
这样您就创建了一个 Server 的实例,另外要注意,端口从 0 到 65535 之间,但是前 1024 端口已经被 TCP/IP 作为保留端口,所以只能选择 1024 之后的端口。这段 code 就建立了以
1234 为端口的 Server。
Server 建立好了,现在需要的是一个 Client 来连接至刚才建立好的 Server。
Socket client = new Socket(InetAddress.getLocalHost(),1234);
由于这个 Client 和 Server 处在同一台机器,所以使用 InetAddress.getLocalHost() 来获得本机的 IP 地址,如果您的 Server 是一个远程的机器,则可以使用它的 IP。例如:Socket client = new Socket( www.test.com, 4321); 此处的域名就是您需要连接的 Server 的 hostname。
建立连接之后,数据的传输还依赖于 Java 的 IO 相关的包,所以还必须引入 java.io 包。Java 的操作也并不复杂,它提供了字节流和 Unicode 的读写,也提供了一些缓冲用于数据的读写。代码 1 给出一个 Client 端的 Socket 编程示例:
public class Client { Socket socket; BufferedReader in; PrintWriter out; public Client() { try { socket = new Socket("xxx.xxx.xxx.xxx", 1234); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(),true); BufferedReader line = new BufferedReader(new InputStreamReader(System.in)); out.println(line.readLine()); line.close(); out.close(); in.close(); socket.close(); } catch (IOException e) { } } …… } |
本文的研究背景是一个正在实施的项目,所以具有一定的现实意义。该项目是对一个具有 40 多年历史的 IBM 主机层次型数据库产品 - IMS 的一个通信组件 IMS Connect 进行自动化测试。本节将首先简要介绍 IMS 及 IMS Connect 的环境及架构,然后描述自动化测试面临的问题。
- IMS 及 IMS Connect 的环境及架构
IMS 是 IBM 的一个软件产品,具有为大型商业应用系统提供事务管理和数据库管理的功能,最初发布于 1968 年,是一个历史悠久的产品。IMS 由数据通信管理器(IMS TM,最初称为 DC),数据库管理器(DB)及一套系统服务设施组成。
IMS 是一个层次型数据的管理系统,只能运行在 z/OS 系统上。DB 主要负责支持 IMS 的层次型数据库模型,它为应用层提供了存储数据库的 API 并且保持数据库的一致性。应用层不需要知道数据库的底层组织,因为有 Data Language/Interface(DL/I,类似于 SQL 的 API)将其分离。而 IMS TM 负责与应用程序进行交互,通过消息队列保持整个通信的顺畅,当然在入队和出队时也会调用到 DL/I 的 API。系统服务组件 TM 和 DB 提供公用的服务,以保持两者的正常工作。图 4 描述了整个 IMS 的简要架构。
IMS Connect 是一个 IMS 的通信组件。通过 IMS Connect 可以使多个 IMS 系统与多个 IMS Connect 的客户端程序保持高效的 TCP/IP 的通信。可以简单把 IMS Connect 理解为外部客户端需要访问的 IMS TCP/IP 服务器。通过这个服务器,任何的 TCP/IP 客户端程序可以与 IMS 建立连接。目前,IMS Connect 对 IMS TM 和 IMS DB 都是支持的。图 5 描述了 IMS Connect 组件在整个 IMS 系统中的位置。图中的 OTMA 是开放事务管理访问,是一个访问协议,ODBM 是开放数据库管理器,负责数据库端的接口。
由于 IMS Connect 是一个 TCP/IP 的服务器,就一定需要开放相应的端口,让客户端程序能够与之通信。IMS Connect 有自己的配置文件,在配置文件中能够自定义需要开放的端口,以及一些 TCP/IP 的 Socket 连接的缓冲设置等。
面临的问题
本文涉及的这个项目正是针对 IMS Connect 配置文件升级的测试。由于 IMS Connect 配置文件更新了,相应的 IMS Connect 作为 TCP/IP 服务器所表现的一些特征也会改变。本文以 IMS Connect 的最大 Socket 连接数配置参数(MAXSOC)为例进行说明。
测试的流程如下:
- 创建 IMS Connect 配置文件 HWSCFG01
- 设置 HWSCFG01 中的 MAXSOC = 60(默认值 50)
- 使用 HWSCFG01 配置文件重新启动 IMS Connect
- 输入 IMS Connect 查看配置参数命令(VIEWHWS),查看 IMS Connect 的最新参数 MAXSOC 是否已经和预期的 60 匹配
- 输入 IMS Connect 查看工作状况的命令(QUERY MEMBER),确保 IMS Connect 按照新的 MAXSOC 参数工作
- 模拟客户端程序发送最大值的 Socket 连接测试 IMS Connect 能按照预期的工作,当到达峰值时拒绝连接。
按照这个测试流程,本文需要实现的情况是在开放平台上创建多个配置文件(HWSCFG01 ~ HWSCFGxx),以边界值测试法尽量覆盖可能的最大 Socket 参数,确保 IMS Connect 正确的工作。图 6 描述了这个测试环境的示意图。
如果所有的工作都在主机环境上进行无疑会减少很多不必要的麻烦,但是由于测试的后续工作主要在模拟客户端发送 Socket 连接以及判断测试是否被拒绝上,所以项目经理选择了在开放平台上做这个交互式的测试。所以本项目的前期工作无疑是解决如何在开放平台与 IBM 大型主机之间进行文件传输的问题。
本文在测试 IMS Connect 项目时,使用了 Rational Functional Tester(RFT) 和 Rational Functional Tester Extension (FTE,一个 z/OS 终端 3270 和 5250 的模拟界面)两个工具。根据 FTE 的界面,另外有一个 TerminalUtility 的工具 Jar 包,用于对 FTE 进行必要输入和操作。
在 RFT 中使用的自动化测试脚本实际上是 Java 语言的 Script,所以要本文在解决开放平台和 IBM 大型主机之间文件传输问题也采用 Java 语言实现。要将之前所述的测试流程自动化,需要在测试流程 1 之后加入关键的一步,即使用 Java 实现将开放平台的配置文件上传至 IMS Connect 需要读取配置文件的功能。这个功能在底层将会用到 FTP 协议,所以可以按照 FTP 协议的要求来逐步完成。
首先,需要获得 IMS Connect 所在主机 IP 地址,在本案例中将会使用 IMS Connect 的产品的特有命令 QUERY MEMBER 来查看 IMS Connect 的运行状况,从而获得 IP 地址。如下图所示 :
为了用 Socke 编程实现文件通过 FTP 协议上载文件的功能,本文创建了 FTPUpload 类。代码 2 给出该类的结构:
public class FTPUpload { String ipAddress; // 需要上传文件的 Server 的 IP address String remotDir; // 需要上传文件到主机的目录 String localFilePath; // 需要上传的开放平台文件路径 String userName; // 用户名 String passWord; // 密码 Socket controlSocket;// 控制用 Socket public PrintWriter controlOutput;// 控制输出用的流 public BufferedReader controlInput;// 控制输入用的流 final int controlPort = 21;// FTP 的控制用端口 ServerSocket serverDataSocket; // 构造函数 FTPUpload(String ipAddress, String username, String password, String remotDir, String localFilePath ){ …… } // 由 ipAddress 和 controlPort 号构造 Socket,形成控制用的流 public void openConnection(String host) throws IOException, UnknownHostException { …… } // 关闭控制用的 Socket public void closeConnection() throws IOException { …… } // 登陆 FTP 服务器 public void login() { …… } // 改变远程的目录 public void changeRemDir() { …… } // 将文件由本地上传至服务器 Public void uploadFile(String remoteFileName){ …… } // 构造与服务器交换数据用的 Socket // 再用 PORT 命令将端口通知服务器 public Socket dataConnection(String ctrlcmd) { …… } // 根据 type 的输入选择不同的传输类型(1-ASCII 2-Binary) public void transferType(int type){ …… } …… …… } |
从结构可以看出,该类有十个基本属性。其中,IBM 主机的 IP 地址、需要的访问账号、密码,本地需要上传的文件目录以及上传需要的远程路径,这个五个属性需要在构造该类的时候给出以便其他方法的执行:
FTPUpload(String ipAddress, String username, String password, String remotDir, String localFilePath ){ this.ipAddress = ipAddress; this.userName = username; this.passWord = password; this.remotDir = remotDir; this.localFilePath = localFilePath; } |
openConnection 方法通过构造的 IP 地址的属性和默认的 FTP 控制端口 21 初始化该类的另一个属性用于控制的 Socket(controlSocket),并且通过 controlSocket 生成需要相应的输入输出流实例。
清单 4 FTPUpload 类 openConnection 函数 :
public void openConnection() throws IOException, UnknownHostException { controlSocket = new Socket(ipAddress, controlPort); controlOutput = new PrintWriter( controlSocket.getOutputStream()); controlInput = new BufferedReader( new InputStreamReader(controlSocket.getInputStream())); } |
doLogin、changeRemDir 和 uploadFile 三个方法是该类的重要方法,负责登陆服务器,改变远程目录和上传文件。dataConnection 方法的功能是建立用于数据传输的 Socket,uploadFile 方法将会调用这个方法来实现。
清单 5 FTPUpload 类 login,changeRemDir,uploadFile 和 dataConnection 函数 :
public void login() { try { controlOutput.println("USER " + userName); controlOutput.flush(); controlOutput.println("PASS " + passWord); controlOutput.flush(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } public void changeRemDir () { try { controlOutput.println("CWD " + remotDir);// CWD 命令 controlOutput.flush(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } public void uploadFile(String remoteFileName) { try { int n; byte[] buff = new byte[1024]; FileInputStream sendfile = null; // 准备读出客户端上的文件 try { sendfile = new FileInputStream(localFilePath); } catch (Exception e) { System.out.println("文件不存在"); return; } // 准备发送数据的流 Socket dataSocket = dataConnection("STOR " + remoteFileName); OutputStream outstr = dataSocket.getOutputStream(); while ((n = sendfile.read(buff)) > 0) { outstr.write(buff, 0, n); } dataSocket.close(); sendfile.close(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } public Socket dataConnection(String ctrlcmd) { String command = "PORT "; int i; Socket dataSocket = null; try { // 本地 IP 地址 byte[] address = InetAddress.getLocalHost().getAddress(); // 使用任意端口构造传输的 socket,backlog 为 1 serverDataSocket = new ServerSocket(0, 1); // 准备传送 PORT 命令用的数据 for (i = 0; i < 4; ++i) command = command + (address[i] & 0xff) + ","; command = command + (((serverDataSocket.getLocalPort()) / 256) & 0xff) + "," + (serverDataSocket.getLocalPort() & 0xff); // 利用控制流先发送 PORT 命令 controlOutput.println(command); controlOutput.flush(); // 发送控制命令 controlOutput.println(ctrlcmd); controlOutput.flush(); dataSocket = serverDataSocket.accept(); serverDataSocket.close(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } return dataSocket; } |
本节将就之前描述的项目背景测试的流程,使用上一节的方法来实现。在本项目中,通过 FTE 的界面使用 TSO 登陆远程的 IBM 主机的测试环境。在测试环境中,IMS Connect 产品使用 USER.PRIVATE.PROCLIB 的 DataSet 作为配置文件的目录。首先验证,在没有上传需要测试的配置文件时,该目录下的情况如下图,可以看出该 DataSet 中目前只有 HWSCFA01 和 SQARCJCL 两个 Member:
图 7. 上传文件之前 USER.PRIVATE.PROCLIB 目录下的 Datasets
需要上传的 IMS Connect 的配置文件如下,以测试 MAXSOC 为例,修改 MAXSOC 为 60:
需要执行的自动化脚本会调用本文实现的 FTPUpload 类的 uploadFile 方法,代码 6 给出了部分脚本:
public void runScenarios1(String configNumber,String[] verifyTitles,String[] verifyContents,int pages){ //Put IMS Connect Config file in UPP and restart FTPupload ftpupload = new FTPupload(hostName, userName,psw,remoteDir1); // 上传 IMS Connect 配置文件 ftpupload.UploadFile(localPath + "C:\\config"+configNumber+".txt", "HWSConfig"+ configNumber); //terminal 为 TerminalUtility 的实例,用来操作 FTE // 重启 IMS Connect,让配置文件生效 terminal.restartIMSConnect(HWS1); // 通过 VIEWHWS 命令验证输出 terminal.imsConnectCommand( ClearBefore, HWS1, IMSConnect.CommandInput.VIEWHWS, "MAXSOC = 60"); // 通过 Query Member 命令验证输出 terminal.mvsCommand( ClearBefore, IMSConnect.CommandInput.QRY_MEMBER("IMSCON"), "MAXSOC = 60"); } |
通过 IMS Connect 的查看 VIEWHWS 命令和 QUERY MEMBER 命令,可见配置文档已经生效,脚本执行成功。
图 9. 通过 VIEWHWS 查看 IMS Connect 的配置
执行脚本之后,重新登陆 TSO,查看相应的目录,新的 IMS Connect 配置文件已经上传成功。
图 10. 上传文件之后 USER.PRIVATE.PROCLIB 目录下的 Datasets
在 FTPUpload 中加入相应的输出 FTP 反馈信息的函数,可以在脚本运行完后可以从 console 窗口打印出 FTP 上传的过程,如下是 console 的部分打印信息:
在本文中,基于项目的需求通过 Java Socket 编程实现了从开放平台到 IBM 主机环境的文件传输的 upload 的功能。基于 FTP 的命令其实有很多,一些常用的如下:
ABOR | 中断数据连接程序 |
ACCT <account> | 系统特权帐号 |
CDUP <dir path> | 改变服务器上的父目录 |
MODE <mode> | 传输模式(S= 流模式,B= 块模式,C= 压缩模式) |
NOOP | 无动作,除了来自服务器上的承认 |
PASV | 请求服务器等待数据连接 |
REIN | 重新初始化登录状态连接 |
SMNT <pathname> | 挂载指定文件结构 |
DELE <filename> | 删除服务器上的指定文件 |
PWD | 显示当前工作目录 |
NLST <directory> | 列出指定目录内容 |
RETR <filename> | 从服务器上找回(复制)文件 |
根据不同的场景,可以将 FTPUpload 进行扩展,在一些跨越两个环境的项目中,可能需要 download 的功能,或者需要上传二进制文件的功能等等,都可以对这种方法进行扩展,以实现不同项目的需求。
为了说明推广的可行性,代码 7 给出了 NLST 命令的示例:
public void list() { try { int n; byte[] buff = new byte[65530]; Socket dataSocket = dataConnection("NLST "); BufferedInputStream dataInput = new BufferedInputStream( dataSocket.getInputStream()); while ((n = dataInput.read(buff)) > 0) { System.out.write(buff, 0, n); } dataSocket.close(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } |
运行该方法后可以得到主机上某个 DataSet 下面的所有 Member 信息,如下:
125 Storing data set USER.PRIVATE.PROCLIB(HWSCFG01) 250 Transfer completed successfully. 200 Port request OK. HWSCFA01 HWSCFG01 SQARCJCL |
在 IBM 大型主机的发展的历程中,伴随的出现了许多主机的产品,例如 CICS、IMS、DB2 等等。这些大型主机的产品的许多配置文件,日志文件都被存在大型主机的 Dataset 中,对在开放平台上的测试人员来说无疑是一个巨大的挑战。当需要进行跨越不同环境的自动化测试时,不可避免的需要使用跨平台的文件传输协议。
本文以 IMS 的 IMS Connect 组件的自动化测试为场景,研究并实现了通过 Java Socket 编程实现的 FTP 文件传输的功能。该实现方法是对 FTP 传输协议客户端的实现,并且还有许多可以扩展的空间,是 Java Socket 编程初学者的较好的示例。本文给出了较为详细的代码示例,并演示和验证了代码的可行性。
最后,本文为可能面临同样的或类似问题的人提供了一些推广和扩展的思路,希望能有利于应用开发或者测试工程师更好的完成工作。
相关推荐
以上就是使用Java Socket编程实现文件上传涉及到的主要知识点,包括Socket通信机制、文件I/O、数据库操作、异常处理、多线程、安全性和性能优化等方面。理解并掌握这些内容,对于开发高效、可靠的文件上传系统至关...
2..instant messaging:使用 Java Socket 编程可以实现即时通信和文件传输。 3.远程教育:使用 Java Socket 编程可以实现远程教育中的实时通信和数据传输。 四、Java Socket 编程的优点 Java Socket 编程有许多...
从给定的文件中,我们可以看到,文件传输服务器端使用了 Java Socket 编程技术,通过 ClientSocket 类实现了客户端和服务器端之间的连接。下面是该文件中所涉及到的知识点: 1. Java Socket 编程基本概念 Java ...
Java Socket网络编程是Java平台中的核心特性,它为开发者提供了在TCP/IP协议下创建网络应用的能力。Socket编程主要用于实现客户端和服务器之间的通信,基于客户机/服务器模型。在这个模型中,服务器端通常处于被动...
Java Socket技术是网络编程中的重要组成部分,主要用于实现两个应用程序之间的通信。在这个场景中,我们讨论的是如何使用Java Socket来实现实时的屏幕监控功能,即服务端能够远程查看客户端的屏幕内容,这样的功能在...
本项目是使用java Socket编程实现的一个简单的FTP服务器和客户端。 客户端目前实现的功能是登录,刷新,上传和下载。同时具有主动模式和被动模式两种模式。 服务器端实现的功能有登录、刷新、上传、下载、列出文件...
在本文中,我们将详细介绍如何使用 Java 的 Socket 编程实现一个简单的多线程 WEB 服务器。 Socket 编程简介 Socket 编程是 Java 网络编程的基础,它允许开发者创建客户端和服务器端的网络应用程序。Socket 是一种...
Java基于Socket实现局域网文件传输,此文件包含了Eclipse项目源码和已经打包好了的.jar文件(文件发送端和文件接收端)。 处在同一局域网内的两台主机,一台运行sender.jar文件(发送端),另一台运行receiver.jar...
本资源是本人前面发过的一个局域网聊天工具的升级版。...代码保证可用,如有问题请留言,代码较规范,结构清晰,相信对学习java socket编程和swing界面开发的朋友有一定的帮助。 注:main函数在MainFrame类
Java Socket 编程总结 Java Socket 编程是Java语言中用于网络编程的主要技术之一。它允许开发者创建网络应用程序,通过Socket实现客户机/服务器结构的通信。在Java中,Socket编程主要是基于TCP/IP协议的网络编程。 ...
总之,利用C语言的socket编程,我们可以实现客户端与服务器之间的文件传输,这是网络通信中的基础操作。通过对socket API的熟练掌握,可以开发出高效、稳定的文件传输应用,满足各种网络环境下的需求。
java socket 实现简单的客户端和服务端通信
在Windows环境下,使用C/C++语言进行Socket编程可以实现客户端和服务端之间的通信以及文件传输。本篇文章将详细探讨如何利用Socket实现这一功能。 首先,我们需要了解Socket的基本概念。Socket是操作系统提供的一种...
Java Socket编程是Java平台中用于实现网络通信的核心API,它基于TCP/IP协议栈,提供了低级别的、面向连接的、可靠的字节流通信。在本文中,我们将深入探讨Java Socket编程的关键概念、工作原理以及如何创建服务端和...
本项目“基于Java Socket网络编程实现的五子棋游戏,可多人在线玩耍,聊天”正是这种技术的实际应用。 首先,我们来深入理解Java Socket编程。Socket是网络通信中的端点,它允许两台计算机(或者网络上的任何其他...
用java socket编写的局域网聊天和文件传送,类似飞秋,但没那么多功能,目前实现的功能有:聊天,发送窗口抖动,传送文件,其中传送文件采用TCP实现,其他的用UDP实现。本文件包含源代码和用到的jar包,代码结构清晰...
Socket编程在Java中是网络通信的核心技术之一,主要用于实现客户端与服务器之间的数据交换。它基于TCP/IP协议,提供了可靠的、面向连接的通信服务。在这个主题中,我们将深入探讨Java中的Socket文件传输编程以及多...
Java Socket 大文件传输是网络编程中的一个关键领域,它涉及到高效的数据传输、包的分片与组装,以及网络协议的选择。在这个场景下,我们通常会用到TCP和UDP这两种传输层协议,以及Java的非阻塞I/O(NIO)技术。下面...
总之,Java 中的 Socket 编程是实现客户端-服务器应用程序的关键技术,它基于 TCP/IP 协议,通过输入输出流进行数据交换。虽然相比其他高级的网络通信库,Socket 编程可能较为繁琐,但它提供了更底层的控制,适用于...
Java语言提供了丰富的Socket编程接口,使得开发者能够方便地实现客户端与服务器之间的数据交换。 #### 二、Socket编程模式 Socket编程主要包括两种基本模式:**TCP (Transmission Control Protocol)** 和 **UDP ...