网络是主机和服务器之间的双向通信,而不是信息交换。任何服务器都被设置为响应客户机请求的特定查询。根据提供给用户的实用程序,有许多不同类型的服务器。例如文件服务器、应用服务器、域服务器等。 让我们举一个例子来演示在客户机-服务器通信模型中如何处理任何客户机的请求。假设有一家X公司有数百名员工,每个人都在自己的系统上工作,他们中的大多数人使用打印机打印一些报告或发票等。在每个系统上安装打印机并不是为用户提供打印设备的一个非常经济的解决方案。另一种方法是设置打印服务器并在该系统上安装打印机。当员工想要打印某件东西时,他或她可以向服务器发送请求,要求为他/她保留打印机。服务器在接收到请求时,客户端编程会根据打印机的可用性、传入请求的速率等诸多因素做出决定,并最终响应请求,告知客户端打印机的状态。任何服务器的一个基本方面是,它应该是特定的,而不是通用的。它不能对每个请求生成类似的响应,而应该根据请求的性质、响应的客户机等进行响应。
本文通过UDP实现了一个简单的计算器服务器,其中客户端将数学公式发送到服务器,服务器将响应该公式的答案。
首先讨论客户端编程,然后讨论服务器端编程。从客户端编程开始,如下所示:
A. 客户端编程
对于通过Internet发送或接收,需要知道侦听实体的套接字地址,即侦听器的IP地址和端口号。通常,客户机知道,或者服务器转发它正在监听的套接字地址。所以在客户端,代码部分几乎没有变化。 客户端不仅调用send()调用,还调用receive()调用。休息所有步骤保持不变。
涉及的步骤如下:
- 创建DatagramSocket: 首先,创建datagramSocket对象,将数据包传送到目的地,并在服务器发送任何数据时接收数据包。
- 创建数据包: 在该步骤中,创建用于经由datagramSocket发送/接收数据的分组。 注意:创建用于发送和接收数据的数据报包的构造函数有所不同
- 对套接字对象调用send()调用: 这将把我们携带方程式的请求发送到服务器进行处理。
- 对套接字对象调用receive()调用: 这用于接收服务器在处理我们的请求后发送的数据。这将冻结我们的程序,直到服务器做出响应,或者如果需要太多时间,就会抛出错误。
例1
JAVA
// Java Program to illustrate Client Side implementation // of Simple Calculator using UDP // Importing required classes import java.io.IOException; // Importing classes fromjava.nio package as // this package is responsible for networking import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Scanner; // Main class // Calc_Client_UDP public class GFG { // Main driver method public static void main(String args[]) throws IOException { // Creating an object of Scanner class to read user // input Scanner sc = new Scanner(System.in); // Step 1 // Create the socket object for carrying data DatagramSocket ds = new DatagramSocket(); InetAddress ip = InetAddress.getLocalHost(); byte buf[] = null ; // loop while user not enters "bye" while ( true ) { System.out.print( "Enter the equation in the format:" ); System.out.println( "'operand1 operator operand2'" ); // Awaiting from entered input String inp = sc.nextLine(); buf = new byte [ 65535 ]; // Converting the String input into the byte // array buf = inp.getBytes(); // Step 2 // Creating the datagramPacket for sending the // data. DatagramPacket DpSend = new DatagramPacket( buf, buf.length, ip, 1234 ); // Invoking the send call to actually send the // data. ds.send(DpSend); // Break the loop if user enters "bye" // using the break keyword if (inp.equals( "bye" )) break ; buf = new byte [ 65535 ]; // Creating an object of DatagramPacket class DatagramPacket DpReceive = new DatagramPacket(buf, buf.length); ds.receive(DpReceive); // Print and display command System.out.println( "Answer = " + new String(buf, 0 , buf.length)); } } } |
输出:
Enter the equation in the form: 'operand operator operand' 5 * 6 Answer=30 Enter the equation in the form: 'operand operator operand' 5 + 6 Answer=11 Enter the equation in the form: 'operand operator operand' 9 / 3 Answer=3
B.服务器端编程
由于通过internet进行通信需要套接字地址,服务器必须知道客户端发送请求的地址。让我们一步一步地看看服务器如何处理端口号问题并响应客户机的查询。
客户端涉及的步骤如下:
- 建立套接字连接 .
- 处理来自客户的方程式: 在服务器端,我们同时打开inputStream和outputStream。在收到方程式后,我们对其进行处理,并将结果发送回客户机。
- 创建用于发送结果的数据包: 这一步会给服务器带来问题,因为它不知道客户端的端口号。为了获得端口,我们使用DatagramPacket类的以下方法。 public int getPort()
语法:
public int getPort() Returns the port number to which the specified datagram packet is being sent to or from which the packet is received.
注: 最后,请记住关闭连接,以避免任何内存泄漏问题。
实例
JAVA
// Java Program Illustrating Server Side Implementation // of Simple Calculator using UDP // Importing required classes import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.StringTokenizer; // Main class // Calc_Server_UDP class GFG { // MAin driver method public static void main(String[] args) throws IOException { // Creating a socket to listen at port 1234 DatagramSocket ds = new DatagramSocket( 1234 ); byte [] buf = null ; // Initializing them initially with null DatagramPacket DpReceive = null ; DatagramPacket DpSend = null ; while ( true ) { buf = new byte [ 65535 ]; // Creating a DatagramPacket to receive the data. DpReceive = new DatagramPacket(buf, buf.length); // Receiving the data in byte buffer. ds.receive(DpReceive); String inp = new String(buf, 0 , buf.length); // Using trim() method to // remove extra spaces. inp = inp.trim(); System.out.println( "Equation Received:- " + inp); // Exit the server if the client sends "bye" if (inp.equals( "bye" )) { System.out.println( "Client sent bye.....EXITING" ); // Exit from program here itself without // checking further break ; } int result; // Use StringTokenizer to break the // equation into operand and operation StringTokenizer st = new StringTokenizer(inp); int oprnd1 = Integer.parseInt(st.nextToken()); String operation = st.nextToken(); int oprnd2 = Integer.parseInt(st.nextToken()); // Perform the required operation if (operation.equals( "+" )) result = oprnd1 + oprnd2; else if (operation.equals( "-" )) result = oprnd1 - oprnd2; else if (operation.equals( "*" )) result = oprnd1 * oprnd2; else result = oprnd1 / oprnd2; System.out.println( "Sending the result..." ); String res = Integer.toString(result); // Clearing the buffer after every message buf = res.getBytes(); // Getting the port of client int port = DpReceive.getPort(); DpSend = new DatagramPacket( buf, buf.length, InetAddress.getLocalHost(), port); ds.send(DpSend); } } } |
输出:
Equation received:-5 * 6 Sending the result... Equation received:-5 + 6 Sending the result... Equation received:-9 / 3 Sending the result...
注: 为了在系统上测试上述程序,请确保先运行服务器程序,然后运行客户端程序。确保您在客户端控制台中,并从那里输入格式为“操作数1运算符操作数2”的等式,然后按enter键。所需方程式的答案将仅显示在客户端控制台中。最后,要终止通信,请键入“bye”(不带引号)并按enter键。
本文由 Rishabh Mahrsee .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。