zoukankan      html  css  js  c++  java
  • Java 网络编程案例二:多台客户端与服务器之间的多次通信

      通常情况下,服务器不应该只接受一个客户端请求,而应该不断地接受来自客户端的所有请求,所以Java程序通常会通过循环,不断地调用ServerSocket的accept()方法。

      如果服务器端要“同时”处理多个客户端的请求,因此服务器端需要为每一个客户端单独分配一个线程来处理,否则无法实现“同时”。

      需求:多个客户端连接服务器,并进行多次通信

      •  每一个客户端连接成功后,从键盘输入单词或词组,并发送非服务器;
      •     服务器收到客户端的消息后,把词语“反转”后返回给客户端;
      •     客户端接收服务器返回的“词语”,打印显示;
      •     当客户端输入“stop”时断开与服务器的连接;
      •     多个客户端可以同时给服务器发送“词语”,服务器可以“同时”处理多个客户端的请求;
      •     服务器端要“同时”处理多个客户端的请求,那么必须使用多线程,每一个客户端的通信需要单独的线程来处理。

      客户端程序示例代码:

     1 import java.io.BufferedReader;
     2 import java.io.InputStream;
     3 import java.io.InputStreamReader;
     4 import java.io.OutputStream;
     5 import java.io.PrintStream;
     6 import java.net.Socket;
     7 import java.util.Scanner;
     8 
     9 public class Client {
    10 
    11     public static void main(String[] args) throws Exception {
    12         // 1、准备Socket,连接服务器,需要指定服务器的IP地址和端口号
    13         Socket socket = new Socket("127.0.0.1", 8888);
    14 
    15         // 2、获取输出流,用来发送数据给服务器
    16         OutputStream out = socket.getOutputStream();
    17         PrintStream ps = new PrintStream(out);
    18         
    19         // 3、获取输入流,用来接收服务器发送给该客户端的数据
    20         InputStream input = socket.getInputStream();
    21         BufferedReader br = new BufferedReader(new InputStreamReader(input));
    22         
    23         Scanner scanner = new Scanner(System.in);
    24         while(true){
    25             System.out.println("输入发送给服务器的单词或成语:");
    26             String message = scanner.nextLine();
    27             if(message.equals("stop")){
    28                 socket.shutdownOutput();
    29                 break;
    30             }
    31             
    32             // 4、 发送数据
    33             ps.println(message);
    34             // 接收数据
    35             String feedback  = br.readLine();
    36             System.out.println("从服务器收到的反馈是:" + feedback);
    37         }
    38         
    39         //5、关闭socket,断开与服务器的连接
    40         scanner.close();
    41         socket.close();
    42     }
    43 }

      服务器端程序示例代码:

     1 import java.net.ServerSocket;
     2 import java.net.Socket;
     3 
     4 public class Server {
     5 
     6     public static void main(String[] args)throws Exception {
     7         // 1、准备一个ServerSocket
     8         ServerSocket server = new ServerSocket(8888);
     9         System.out.println("等待连接...");
    10         
    11         int count = 0;
    12         while(true){
    13             // 2、监听一个客户端的连接
    14             Socket socket = server.accept();
    15             System.out.println("第" + ++count + "个客户端连接成功!!");
    16             
    17             ClientHandlerThread ct = new ClientHandlerThread(socket);
    18             ct.start();
    19         }
    20         
    21         //这里没有关闭server,永远监听
    22     }
    23 }

      服务器端处理客户端请求的线程类示例代码:

     1 import java.io.BufferedReader;
     2 import java.io.IOException;
     3 import java.io.InputStreamReader;
     4 import java.io.PrintStream;
     5 import java.net.Socket;
     6 
     7 public class ClientHandlerThread extends Thread{
     8     private Socket socket;
     9 
    10     public ClientHandlerThread(Socket socket) {
    11         super();
    12         this.socket = socket;
    13     }
    14     
    15     public void run(){
    16         
    17         try{
    18             //(1)获取输入流,用来接收该客户端发送给服务器的数据
    19             BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    20             //(2)获取输出流,用来发送数据给该客户端
    21             PrintStream ps = new PrintStream(socket.getOutputStream());
    22             String str;
    23             // (3)接收数据
    24             while ((str = br.readLine()) != null) {
    25                 //(4)反转
    26                 StringBuilder word = new StringBuilder(str);
    27                 word.reverse();
    28                 
    29                 //(5)返回给客户端
    30                 ps.println(word);
    31             }
    32         }catch(Exception  e){
    33             e.printStackTrace();
    34         }finally{
    35             try {
    36                 //(6)断开连接
    37                 socket.close();
    38             } catch (IOException e) {
    39                 e.printStackTrace();
    40             }
    41         }
    42     }
    43 }
  • 相关阅读:
    VS2010中的单元测试
    GSM局数据制作2(Erision)
    WPF的BitmapImage的文件无法释放及内存泄露的问题
    跨库查询推荐使用的方法
    我们能做什么呢?
    长尾理论:Windows Vista
    Blackberry阻碍因素
    RIM终于想通了RIM开放新的API
    Prototype库终于有了文档了
    自己编写的MSN历史记录合并工具
  • 原文地址:https://www.cnblogs.com/niujifei/p/12291735.html
Copyright © 2011-2022 走看看