一個Java多線程阻塞模式通信的例子

程序分Server和Client

服務器端打開偵聽的端口,一有客戶端連接就創建兩個新的線程來負責這個連接

一個負責客戶端發送的信息(ClientMsgCollectThread 類),

另一個負責通過該Socket發送數據(ServerMsgSendThread )

Server.java代碼如下:

/*
 * 創建日期 2009-3-7
 *
 * TODO 要更改此生成的文件的模板,請轉至
 * 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板
 */
package faue.MutiUser;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服務器端
 * 
 * @author Faue
 */
public class Server extends ServerSocket {

 private static final int SERVER_PORT = 10000;

 /**
  * 構造方法,用於實現連接的監聽
  * 
  * @throws IOException
  */
 public Server() throws IOException {
  super(SERVER_PORT);

  try {
   while (true) {
    Socket socket = super.accept();

    new Thread(new ClientMsgCollectThread(socket), "getAndShow"
      + socket.getPort()).start();
    new Thread(new ServerMsgSendThread(socket), "send"
      + socket.getPort()).start();

   }
  } catch (IOException e) {
   e.printStackTrace();
  }

 }

 public static void main(String[] args) throws IOException {
  new Server();
 }

 /**
  * 該類用於創建接收客戶端發來的信息並顯示的線程
  * 
  * @author Faue
  * @version 1.0.0
  */
 class ClientMsgCollectThread implements Runnable {

  private Socket client;

  private BufferedReader in;

  private StringBuffer inputStringBuffer = new StringBuffer("Hello");

  /**
   * 得到Socket的輸入流
   * 
   * @param s
   * @throws IOException
   */
  public ClientMsgCollectThread(Socket s) throws IOException {
   client = s;

   in = new BufferedReader(new InputStreamReader(client
     .getInputStream(), "GBK"));
  }

  public void run() {
   try {

    while (!client.isClosed()) {
     inputStringBuffer.delete(0, inputStringBuffer.length());
     inputStringBuffer.append(in.readLine());

     System.out.println(getMsg(inputStringBuffer.toString()));
    }
   } catch (IOException e) {
    //e.printStackTrace();
    System.out.println(client.toString() + " is closed!");

   }
  }

  /**
   * 構造顯示的字符串
   * 
   * @param line
   * @return
   */
  private String getMsg(String line) {
   return client.toString() + " says:" + line;
  }

 }

 /**
  * 該類用於創建發送數據的線程
  * 
  * @author Faue
  * @version 1.0.0
  */
 class ServerMsgSendThread implements Runnable {

  private Socket client;

  private PrintWriter out;

  private BufferedReader keyboardInput;

  private StringBuffer outputStringBuffer = new StringBuffer("Hello");

  /**
   * 得到鍵盤的輸入流
   * 
   * @param s
   * @throws IOException
   */
  public ServerMsgSendThread(Socket s) throws IOException {
   client = s;

   out = new PrintWriter(client.getOutputStream(), true);
   keyboardInput = new BufferedReader(new InputStreamReader(System.in));

  }

  public void run() {
   try {

    while (!client.isClosed()) {
     outputStringBuffer.delete(0, outputStringBuffer.length());
     outputStringBuffer.append(keyboardInput.readLine());

     out.println(outputStringBuffer.toString());
    }
   } catch (IOException e) {
    //e.printStackTrace();
    System.out.println(client.toString() + " is closed!");

   }
  }

 }

}

 客戶端:

實現基於IP地址的連接,連接後也創建兩個線程來實現信息的發送和接收

 

/*
 * 創建日期 2009-3-7
 * 
 */
package faue.MutiUser;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

/**
 * 客戶端
 * 
 * @author Faue
 */
public class Client {

 private Socket mySocket;

 /**
  * 創建線程的構造方法
  * 
  * @param IP
  * @throws IOException
  */
 public Client(String IP) throws IOException {

  try {
   mySocket = new Socket(IP, 10000);
   new Thread(new ServerMsgCollectThread(mySocket), "getAndShow"
     + mySocket.getPort()).start();
   new Thread(new ClientMsgSendThread(mySocket), "send"
     + mySocket.getPort()).start();

  } catch (IOException e) {
   //e.printStackTrace();
   System.out.println("Server.IP:" + IP
     + " port:10000 can not be Connected");
  }
 }

 public static void main(String[] args) throws IOException {
  try {
   new Client(args[0]);
  } catch (Exception e) {
   System.out.println("輸入的IP地址錯誤");
  }
 }

 /**
  * 該類用於創建接收服務端發來的信息並顯示的線程
  * 
  * @author Faue
  * @version 1.0.0
  */
 class ServerMsgCollectThread implements Runnable {

  private Socket client;

  private BufferedReader in;

  private StringBuffer inputStringBuffer = new StringBuffer("Hello");

  /**
   * 得到Socket的輸入流
   * 
   * @param s
   * @throws IOException
   */
  public ServerMsgCollectThread(Socket s) throws IOException {
   client = s;

   in = new BufferedReader(new InputStreamReader(client
     .getInputStream(), "GBK"));
  }

  public void run() {
   try {

    while (!client.isClosed()) {
     inputStringBuffer.delete(0, inputStringBuffer.length());
     inputStringBuffer.append(in.readLine());
     System.out.println(getMsg(inputStringBuffer.toString()));
    }
   } catch (IOException e) {
    //e.printStackTrace();
    System.out.println(client.toString() + " is closed!");
    System.exit(0);
   }
  }

  /**
   * 構造輸入字符串
   * 
   * @param line
   * @return
   */
  private String getMsg(String line) {
   return client.toString() + " says:" + line;
  }

 }

 /**
  * 該類用於創建發送數據的線程
  * 
  * @author Faue
  * @version 1.0.0
  */
 class ClientMsgSendThread implements Runnable {

  private Socket client;

  private PrintWriter out;

  private BufferedReader keyboardInput;

  private StringBuffer outputStringBuffer = new StringBuffer("Hello");

  /**
   * 得到鍵盤的輸入流
   * 
   * @param s
   * @throws IOException
   */
  public ClientMsgSendThread(Socket s) throws IOException {
   client = s;

   out = new PrintWriter(client.getOutputStream(), true);
   keyboardInput = new BufferedReader(new InputStreamReader(System.in));

  }

  public void run() {
   try {

    while (!client.isClosed()) {
     outputStringBuffer.delete(0, outputStringBuffer.length());
     outputStringBuffer.append(keyboardInput.readLine());

     out.println(outputStringBuffer.toString());
    }
    out.println("--- See you, bye! ---");
   } catch (IOException e) {
    //e.printStackTrace();
    System.out.println(client.toString() + " is closed!");
    System.exit(0);
   }
  }

 }

} 

 

此文主要用來與非阻塞通信作比較

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章