写点什么

手把手教会你 | 网络编程

作者:TiAmo
  • 2023-05-06
    江苏
  • 本文字数:4061 字

    阅读完需:约 13 分钟

手把手教会你 | 网络编程

01.什么是 Java 的 Socket 技术?


Socket 技术属于 TCP(Transfer Control Protocol),是一种面向连接传输(Connection- oriented transmission)通信协议。这种通信协议首先建立计算机间的通信连接,然后再进行数据的传送和交换。Java 的 Socket 编程技术以及 API 类 Socket、ServerSocket,就是面向连接传输的具体体现。发送方(Socket 对象),或者用户,和服务方(ServerSocket 对象),或者服务器,必须首先建立连接,以便在 TCP 协议基础上实现通信。当一个用户端程序中的 Socket 对象发出连接请求,服务器端程序中的 ServerSocket 对象,可接受或者拒绝这个请求。一旦这两个 Sockets 对象实现连接,它们则可以进行双向数据传输,双方都可以进行数据发送和接收操作。这个解释也同样适用于应用 Socket 技术设计的多用户-服务器编程和多层次-多用户-服务器编程。


简言之,Sockets,即 IP 地址+端口号,也称套接字,是利用软件技术虚拟通信设备,通过端口进行计算机间的通信。它形象化地描述这个通信过程,如同把设备(用户端计算机)插入指定插座(服务器)一样容易。虽然 Socket 属于底层通信技术,但通过 Java 提供的 API 类,可实现不必了解底层通信详情,通过创建对象和调用适当的方法,进行用户-服务器应用软件开发和编程。Socket 技术也是用户-服务器编程的基础,JSP(Java Server Pages)、RMI、Java EE 以及其他 Java 网络编程技术,都基于 Socket 概念和技术。


与 Sockets/TCP 通讯技术相对应的是 UDP(User Datagram Protocol),则是一种面向传输,即 Transmission-oriented connection 通信协议。UDP 在数据通信过程中并不要求、也不保持计算机间的通信连接。用户计算机通过数据报表 datagram,或邮包 packet 形式,发送请求给另外一台计算机后。双方的连接并不继续保持。每个邮包都有其字节长度、独立的发送方地址、接收方地址以及通信端口。它在网络上可能以任何路径进行传递并到达目的地。


02.、Sockets 单用户-服务器编程


这个小节讨论基本 Java 网络编程技术。首先,我们将在 Java 程序中利用 Socket 与服务器进行通信,请求、获取并显示服务器发回的数据。还将进一步讨论 HTTP 通信协议和技术,学习 Java 在 URL 编程方面的应用实例。


Sockets 单用户-服务器编程步骤

1. 设计、编写用户端程序。首先利用 Socket 编写用户端程序。创建 Socket 对象并且请求连接指定的服务器、调用 Socket 的方法,利用数据流技术发送对服务器的请求信息、并提取服务器传送回来的数据。

2. 设计、编写服务器端对应的服务程序。利用 ServerSocket 创建对象、调用其方法,利用数据流技术接受用户端的连接请求、得到用户端的请求信息、并发送所请求的数据。


代码实例:Sockets 单用户-服务器编程

首先解释常用的利用 Socket 以及 ServerSocket 进行用户-服务器编程的 API 类。表 1 列出了 java.net 包中提供的常用 Socket 和 ServerSocket 的构造方法和方法。

表 1 常用 Socket 和 ServerSocket 构造方法和其他方法



注意:Socket 和 ServerSocket 抛出检查性异常,程序中必须提供处理这些异常的代码。具体实例见下面的讨论。


下面的例子利用 Socket 和 ServerSocket,模拟用户-服务器通信,将用户的英文输入,发送到服务器端程序,转换为大写字母,并将结果传回到用户屏幕。如下显示了这个例子的一个典型运行结果。第一行显示了服务器端程序运行、连接用户的成功。下方为用户端程序运行、输入请求、得到回答以及停止程序运行的对话通信过程:

Server: Welcome! The server is running....Server: Type quit to STOPClient: java programmingServer: JAVA PROGRAMMINGClient: socket and sockectServer client-server programmingServer: SOCKET AND SOCKECTSERVER CLIENT-SERVER PROGRAMMINGClient: quitServer: Bye!Client: Now is disconnected...
复制代码

如下是用户端的程序代码:

//这个程序存在本文压缩附件中名为SocketClientTest.java源代码//Socket simple client application: connect to server to convert entries to upper caseimport java.io.*;import java.net.*;import java.util.*;public class SocketClientTest {  public static void main(String[] args) {    try {       Socket clientSocket = new Socket("localhost", 1688); //本地计算机模拟;使用端口1688      InputStream inData = clientSocket.getInputStream(); //得到服务器输入流       OutputStream outData = clientSocket.getOutputStream(); //建立输出流至服务器       PrintWriter toServer = new PrintWriter(outData, true); //发送输出流       Scanner sc = new Scanner(System.in); //键盘输入扫描       Scanner data = new Scanner(inData); //服务器输入扫描       String heding = data.nextLine(); //得到服务器第一行输入信息      System.out.println(heading); //打印这行信息      while (sc.hasNextLine()) { //键盘输入循环         String line = sc.nextLine(); //得到键盘输入        toServer.println(line); //传送到服务器         String fromServer = data.nextLine(); //得到服务器回答        System.out.println(fromServer); //打印        if (fromServer.equals("Bye!")) { //如果传回结果为停止运行          System.out.println("Now is disconnected...");          break;         }       }      clientSocket.close();    }  catch (IOException e) { //处理检查性异常      e.printStackTrace();    }   } }
复制代码


这个用户端程序利用 localhost 和端口 1688(可以是 1024~65535 之间的任何一个端口),进行用户-服务器之间的数据交流。在把用户从键盘输入的数据传送给服务器时,使用 PrintWriter 创建一个封装有 Socket 输出流至服务器的对象 outData,并利用 true 作为选项,实现对输入流缓冲器的实时刷新。程序中还利用 Scanner 创建了封装有服务器端输入流 inData 的对象 data,用来扫描从服务器传送过来的数据,并将其显示到屏幕上。


如同文件 I/O,Socket 抛出的异常为检查性异常。如果连接失败,Socket 将抛出 UnknownHostException 以及 IOException;其他 Socket 方法将抛出 IOException。因为 UnknownHostException 是 IOException 的子类,代码中利用 IOException 来捕获所有的异常。


创建 Socket 对象将执行与指定服务器通过规定端口连接操作。这时,其他代码将暂停运行,直到连接完毕,或抛出连接异常。为了防止无终止等待,或控制等待时间,可以在代码中创建了 clientSocket 后,利用 setSoTimeOut()方法,加入如下控制用户与服务器通信时间的语句:

clientSocket.setSoTimeout(1000); //设置连接时间为1秒
复制代码

如下程序为服务器端代码:

//这个程序存在本文结尾压缩文件中名为SocketServerTest.java源代码//Socket simple server application: convert client's entries to upper case//SocketServer codeimport java.io.*;import java.net.*;import java.util.*;public class SocketServerTest {  public static void main(String[] args) {    System.out.println("Welcome! The server is running...");      try {         ServerSocket server = new ServerSocket(1688); //监控端口为1688         Socket fromClient = server.accept(); //接受用户的连接请求         InputStream inData = fromClient.getInputStream(); //得到用户输入流         OutputStream outData = fromClient.getOutputStream(); //得到用户输出流         PrintWriter toClient = new PrintWriter(outData, true); //创建输出流        toClient.println("Type quit to STOP"); //发送信息到用户         Scanner data = new Scanner(inData); //用户输入扫描        while (data.hasNextLine()) {           String line = data.nextLine(); //得到用户输入数据          if (line.equalsIgnoreCase("quit")) { //如果是停止运行            server.close(); //关闭连接            toClient.println("Bye!"); //发送信息            break;           }          toClient.println(line.toUpperCase());//否则发送转换为大写字母信息         }       }      catch (IOException e) {        e.printStackTrace();       }   } }
复制代码

服务器端程序首先利用 ServerSocket 创建有指定监控端口的对象,并调用 accept()方法来接受任何从这个端口试图连接这个服务器的请求。代码其他部分与用户端程序相似,这里不再一一赘述。如果用户传送来的信息为 quit,程序将关闭连接,停止运行。程序中调用 String 的 toUpperCase()方法,把用户传送过来的信息,转换成大写字母,并将其传回至用户端。


注意:测试时,首先运行服务器端程序,再运行用户端代码。


Socket 单用户-服务器程序测试运行步骤

建议你先在本地计算机模拟运行上节讨论的单用户-服务器程序,连接并调试程序的运行。其步骤如下:

1.在 Eclipse 中首先运行服务器端程序,如 SocketServerTest。

2.在 Eclipse 中运行用户端程序,如 SocketClientTest。

3.为更好模拟运行,可将用户端程序拷贝(注意不包括包名 ch23)到一个本机文件夹中,如 C:\Temp。打开一个操作系统窗口,打入如下编译指令:

javac SocketClientTest.java
复制代码

再打入如下运行指令:

java SocketClientTest
复制代码

以上步骤适合于本书所讨论的所有单用户-服务器程序测试。


你可以在本地计算机运行成功后,在用户端代码中将 localhost(或 127.0.0.1)改为作为服务器的计算机 IP 地址,例如 192.168.15.101,这样,就可在任何两个有网络连接的计算机上运行服务器端程序以及用户端程序。计算机的 IP 地址可用前面介绍过的指令 ipconfig 在操作系统窗口中获得。注意由于网络安全、联网设置和访问规范问题,需要对联网的计算机进行设置上的调整和更新。


如下是在有网络连接的计算机上测试的方法。其运行步骤如下:

1.在作为服务器的计算机的操作系统窗口中输入:

ipconfig 指令,获得其 IP 地址,如:192.168.15.101。

2.将用户端代码中的 localhost 修改为作为服务器端计算机的 IP 地址。

3.运行服务器端程序。

4.在联网的另外一个计算机上运行用户端程序。

发布于: 刚刚阅读数: 2
用户头像

TiAmo

关注

有能力爱自己,有余力爱别人! 2022-06-16 加入

CSDN全栈领域优质创作者,万粉博主;阿里云专家博主、星级博主、技术博主、阿里云问答官,阿里云MVP;华为云享专家;华为Iot专家;亚马逊人工智能自动驾驶(大众组)吉尼斯世界纪录获得者

评论

发布
暂无评论
手把手教会你 | 网络编程_socket通信_TiAmo_InfoQ写作社区