1. 程式人生 > >【Java TCP/IP Socket程式設計】----套接字----TCP Socket

【Java TCP/IP Socket程式設計】----套接字----TCP Socket

簡介

    TCP通訊嚴格區分客戶端和伺服器端,通訊時客戶端發起請求連線伺服器端才能實現通訊,伺服器端不能主動連線客戶端。Java為TCP協議提供了兩個類:Socket類和ServerSocket類,一個Socket例項代表了TCP連線的客戶端,而ServerSocket例項代表了TCP連線的伺服器端。一個TCP連線是一條抽象的雙向通道,兩端分別由IP地址和埠號確定。開始通訊之前,要建立一個TCP連線,這需要先由客戶端TCP向服務端TCP傳送連線請求。ServerSocket例項則監聽TCP連線請求,併為每個請求建立新的Socket例項,也就是說伺服器端要同時處理ServerSocket例項和Socket例項,而客戶端只需要使用Socket例項。

TCP通訊

TCP客戶端:

    客戶端向伺服器發起連線請求,就被動地等待伺服器的響應。典型的TCP客戶端要經過下面三步。

    1.建立一個Socket例項:建構函式向指定的遠端主機和埠建立一個TCP連線。

    2.通過套接字的輸入輸出流進行通訊,一個Socket連線例項包括了一個InputStream和一個OutputStream。

    3.使用Socket類的close()方法關閉連線。

TCP伺服器端:

    伺服器端的工作是建立一個通訊終端,並被動地等待客戶端的連線。典型的TCP伺服器質性如下工作:

    1.建立一個ServerSocket例項並指定本地埠。此套接字的功能是監聽改指定埠收到的連線。

    2.重複執行:

      a.呼叫ServerSocket的accept()方法以獲取下一個客戶端連線。基於新建立的客戶端連線,建立一個Socket例項,並由accept()方法返回。

        b.使用所返回的Socket例項的InputStream和OutputStream與客戶端進行通訊。

        c.通訊完成後,使用Socket類的close()方法關閉該客戶端套接字連線。

TCP通訊案例

以下程式碼實現了客戶端傳送檔案到伺服器端,伺服器端進行接收並儲存檔案,接收完檔案給客戶端反饋。

此案例使用多執行緒實現的,由此服務端可以接收到多個客戶端傳送過來的檔案。

public class TCPClient {
  public static void main(String[] args) {
    try {
      Socket clientSocket = new Socket("127.0.0.1", 1234);
      BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\java.txt"));
      OutputStream out = clientSocket.getOutputStream();
      int len = 0;
      byte[] buffer = new byte[1027];
      while ((len = bis.read(buffer)) != -1) {
        out.write(buffer, 0, len);
      }
      // 資料傳送完畢,關閉socket輸出操作,告知伺服器端
      clientSocket.shutdownOutput();
      // ---------讀取伺服器端的反饋資訊
      InputStream in = clientSocket.getInputStream();
      byte[] message = new byte[1024];
      int length = in.read(message);
      System.out.println(new String(message, 0, length));
      // 關閉套接字和流
      clientSocket.close();
      bis.close();
      out.close();
      in.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}
public class ServerTask implements Runnable {

  private Socket clientSocket;

  public ServerTask(Socket socket) {
    this.clientSocket = socket;
  }

  @Override
  public void run() {
    try {
      InetAddress address = clientSocket.getInetAddress();
      System.out.println("message from ip:" + address.getHostAddress());
      InputStream in = clientSocket.getInputStream();
      BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\upload"+System.currentTimeMillis()+".txt"));
      int len = 0;
      byte[] buffer = new byte[1024];
      while ((len = in.read(buffer)) != -1) {
        bos.write(buffer, 0, len);
      }
      // --------給客戶端反饋
      OutputStream out = clientSocket.getOutputStream();
      out.write("finish the job".getBytes());
      in.close();
      bos.close();
      out.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}
public class TCPServer {
  public static void main(String[] args) throws IOException {
    //監聽埠1234
    ServerSocket serverSocket = new ServerSocket(1234);
   while(true) {
     //請求啟用一個執行緒處理
     Socket clientSocket = serverSocket.accept();
     new Thread(new ServerTask(clientSocket)).start();
   }
   //serverSocket.close();
  }
}