专注Java教育14年 全国咨询/投诉热线:444-1124-454
赢咖4LOGO图
始于2009,口口相传的Java黄埔军校
首页 学习攻略 Java学习 Java客户端与服务器程序

Java客户端与服务器程序

更新时间:2022-06-21 12:36:21 来源:赢咖4 浏览1059次

Java中的客户端服务器程序

客户端和服务器是套接字编程的两个主要组件。客户端是请求服务的计算机/节点,服务器是响应客户端的计算机/节点。在 Java 中,使用套接字编程,我们可以连接客户端和服务器。

套接字是用于发送和接收消息的端点。它是 IP 地址和端口号的组合。客户端-服务器程序中使用了两种类型的套接字:一种是客户端套接字,另一种是服务器套接字。在客户端-服务器程序中,客户端必须知道客户端想要发送服务请求的服务器端点的位置(IP 地址和端口号)。在计算机世界中,客户端和服务器都是应用程序。服务器程序使用服务器套接字,而客户端程序使用客户端套接字进行通信。

以下 Java 程序说明了如何在客户端和服务器之间建立通信。让我们从客户端程序开始。

客户端程序

// 导入语句
 导入java.net.*;
 导入java.io.*;
 导入 java.util.Scanner;
 公共类客户端
 {
     // 初始化套接字和输入输出流
     私有数据输出流数据输出 = null;
     私人扫描仪 sc = null;
     私有套接字 skt = null;
     // 构造函数来创建具有给定 IP 和端口地址的套接字
     公共客户端(字符串地址,int 端口)
     {
         // 与服务器建立连接
         尝试
         {
              // 创建一个socket对象
             skt = 新套接字(地址,端口);
             System.out.println("连接建立!!");
             System.out.println("输入 \"Finish\" 终止连接。");
             // 从用户那里获取输入
             sc = 新扫描仪(System.in);
             // 在套接字上打开输出流
             dataOut = new DataOutputStream(skt.getOutputStream());
         }
         catch(UnknownHostException 呃)
         {
             System.out.println(uh);
         }
         捕捉(IOException io)
         {
             System.out.println(io);
         }
         // 存储用户输入的信息
         字符串 str = "";
         // 继续读取直到输入“Finish”
         而(!str.equals(“完成”))
         {
             输入 = sc.nextLine(); // 读取输入
             尝试
             {
                 dataOut.writeUTF(str); // 写入底层输出流
             }
             // 用于在写入输出流时处理错误
             捕捉(IOException io)
             {
                 System.out.println(io);
             }
         }
         System.out.println("连接终止!!");
         // 用于关闭连接
         尝试
         {
             数据输出.close();
             skt.close();
         }
         捕捉(IOException io)
         {
             System.out.println(io);
         }
     }
     公共静态无效主要(字符串argvs [])
     {
          // 创建类Client的对象
         ClientSide client = new ClientSide("localhost", 6666);
     }
 }

解释:我们知道要建立连接,客户端和服务器端都需要套接字。以下语句在客户端创建一个套接字:

sk = 新套接字(地址,端口);

Socket 类的构造函数有两个参数:一个是地址(IP 地址),另一个是端口(端口号),并创建了 Socket 类的对象。在代码中,我们使用了端口号 6666。这里,我们使用了 localhost,因为客户端应用程序和服务器应用程序运行在同一个系统上。通常,客户端程序和服务器程序位于不同的系统上。在这种情况下,使用运行服务器的系统的 IP 地址而不是 localhost。确保在这种情况下使用完全限定的 IP 地址/名称。

端口号 6666 表示客户端正在尝试在端口 6666 上建立与服务器的连接。如果服务器在端口 6666 上,则连接建立;否则,不是。

该声明

dataOut = new DataOutputStream(skt.getOutputStream());
 dataOut.writeUTF(str);

写入在套接字上打开的输出流。服务器正在读取输出流上写入的任何内容。这里,str是一个字符串,它读取用户输入的任何内容。变量str的读取将继续,直到用户输入“Finish”。如果在写入底层流时发生任何错误,IOException的 catch 块就会出现。

如果我们在 Socket 类的构造函数的参数中提供任何无效的 IP 地址,则上述 catch 块的以下代码片段将生效。

catch(UnknownHostException 呃)
 {
 System.out.println(uh);
 }

例如,如果我们键入“locahost”而不是“localhost”,则上述 catch 块的语句将生效。

现在,让我们讨论一下服务器端程序。

服务器端程序

// 导入语句
 导入java.net.*;
 导入java.io.*;
 公共类服务器
 {
     //初始化输入流和套接字
     私有数据输入流 inStream = null;
     私有套接字 skt = null;
     私有 ServerSocket srvr = null;
     // 类Server的构造函数
     公共服务器(int 端口)
     {
         // 启动服务器并等待客户端 
         尝试
         {
             srvr = 新服务器套接字(端口);
             System.out.println("服务器启动");
             System.out.println("正在等待客户端连接...");  
             skt = srvr.accept(); // 等待客户端发送连接请求
             System.out.println("与客户端连接!!");
             // 使用套接字接收来自客户端的输入消息
             inStream = new DataInputStream(skt.getInputStream());
             字符串 str = ""; // 用于读取客户端发送的消息的变量
             // 直到客户端发送“完成”,
             // 继续阅读消息
             而(!str.equals(“完成”))
             {
                 尝试
                 {
                     // 从底层流中读取
                     str = inStream.readUTF();
                     // 在控制台上打印读取的消息
                     System.out.println(str);
                 }
                // 用于处理错误
                 捕捉(IOException io)
                 {
                     System.out.println(io);
                 }
             }
             //关闭已建立的连接
             skt.close();
             inStream.close();
             System.out.println("连接关闭!!");
         }
         // 处理错误
         捕获(IOException 我)
         {
             System.out.println(i);
         }
     }
     公共静态无效主要(字符串argvs [])
     {
         // 创建类ServerSide的对象
         服务器服务器=新服务器(6666);
     }
 }

解释:声明

srvr = 新服务器套接字(端口);

创建一个新套接字并将其绑定到端口号,该端口号作为参数(端口)传递给类ServerSocket的构造函数。在代码中,我们使用了端口号 6666。这意味着服务器正在侦听端口号 6666,客户端必须使用此端口号(6666)连接到服务器。

该声明

skt = srvr.accept();

服务器使用它来接受来自客户端的连接请求。服务器在调用方法accept() 后等待。等待一直持续到服务器从客户端收到连接请求。在这里,等待意味着在accept()方法之后编写的任何语句在服务器收到连接请求之前不会被执行。在这个位置,我们说服务器正在监听给定的端口号,在我们的例子中是 6666。

为了读取客户端发送的消息,我们必须打开一个到套接字的输入流。以下语句也是如此。

inStream = new DataInputStream(skt.getInputStream());

getInputStream()方法返回附加到套接字的输入流。在 Java 中,数据输出流用于写入可以稍后由输入流读取的数据。上述声明中也发生了同样的情况。当我们调用DataInputStream类的readUTF()方法时,我们从客户端发送的任何内容都会被读取。下面的语句做同样的事情

str = inStream.readUTF();

在客户端,我们使用writeUTF()方法对流进行写入部分。同样,在服务器端,我们在这里使用了 readUTF() 从流中读取部分。readUTF ()方法返回一个 Unicode 字符串,我们将其存储在变量str 中。继续阅读,直到客户端发送“完成”一词。阅读“完成”一词后,连接将关闭。下面的书面陈述达到了同样的效果。

skt.close();
 inStream.close();

执行步骤

首先,应该执行服务器端程序。这是因为,当我们开始执行客户端程序时,它开始在端口号 6666 处寻找服务器。由于我们没有先执行服务器端程序,因此不会有服务器在侦听端口号 6666。因此,客户端程序引发NullPointerException。因此,客户端程序必须在服务器端程序执行之后执行。

为了执行上述程序,打开两个命令提示符,一个用于客户端程序,另一个用于服务器端程序。分别使用命令javac和java进行编译和执行。

输出:

首先,我们执行服务器端程序。

我们看到执行后,服务器等待客户端连接。现在,执行客户端程序并观察服务器如何响应。

我们看到服务器响应消息Connected with a client!! 现在,连接已经建立,我们可以向连接的服务器发送消息。观察以下快照。

1234, 78, ..., Russia 是客户端发送的输入。这些输入消息在服务器端显示。要终止连接,我们必须输入单词 Finish。

输入“完成”一词后,两边的连接都关闭了。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>