廖雪峯Java13網絡編程-1Socket編程-2TCP編程

1. Socket

在開發網絡應用程序的時候,會遇到Socket這個概念。
Socket是一個抽象概念,一個應用程序經過一個Socket來創建一個遠程鏈接,而Socket內部經過TCP/IP協議把數據傳輸到網絡。

Socket/TCP/部分IP都是由操做系統提供的。不一樣的編程語言只是提供了對操做系統調用的加單封裝,例如Java提供的幾個Socket相關的類就封裝了操做系統提供的接口。
爲何須要Socket?
由於僅僅經過IP地址進行通訊還不夠,同一臺計算機同一時間會運行多個網絡程序。當計算機收到一個數據包的時候,只有IP地址是無法判斷應該發送給哪一個應用程序的,因此操做系統抽象出Socket接口。每一個應用程序須要對應不一樣的Socket,能夠把Socket簡單理解爲IP地址+端口號。
端口號是操做系統分配的,是在0-65535之間的數字java

  • <1024是特權端口,須要管理員權限
  • >1024的端口能夠由任意應用程序打開

2. Socket使用

Socket編程模型須要實現服務器端與客戶端,由於2個應用程序通訊的時候不只須要對方的IP,還須要知道對方的端口號。因此服務器端必須先固定一個端口號,例如80。客戶端在發起請求的時候,會直接請求80端口,同時告知本身的端口,這樣雙方就能夠經過Socket進行通訊了。
客戶端的編程:編程

Socket sock = new Socket(InetAddress,port);//鏈接到遠程服務器的指定端口
    InputStream in = sock.getInputStream();//獲取到輸入和輸出流
    OutputStream out = sock.getOutputStream();    
    //讀寫字節流

服務器端:緩存

ServerSocket ss = new ServerSocket(port); //監聽指定端口號
    Socket sock = ss.accept();
    InputStream in = sock.getInputStream();
    OutputStream out = sock.getOutputStream();
    //讀寫字節流

TCPClient.java服務器

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class TCPClient {
    public static void main(String[] args) throws IOException{
        InetAddress addr = InetAddress.getLoopbackAddress(); //獲取本機的InetAddress,一般是127.0.0.1
        try(Socket sock = new Socket(addr,9090)){ //打開遠程鏈接
            try(BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream(),StandardCharsets.UTF_8))){//BufferedReader類就是一個包裝類,它能夠包裝字符流,將字符流放入緩存裏,到緩存滿了或者執行flush的時候,再讀入內存,能夠提交讀的效率。
                try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream(),StandardCharsets.UTF_8))){
                    writer.write("time\n");
                    writer.flush();//強制把緩存區的內容發送出去
                    String resp = reader.readLine();
                    System.out.println("Response:"+resp);
                }
            }
        }
    }
}

TCPServer.java網絡

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.time.LocalTime;

public class TCPServer {
    public static void main(String[] args) throws Exception{
        ServerSocket ss = new ServerSocket(9090);
        System.out.println("TCP Server ready:");
        Socket sock = ss.accept();
        try(BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream(),StandardCharsets.UTF_8))){
            try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream(),StandardCharsets.UTF_8))){
                String cmd = reader.readLine(); //獲取客戶端傳過來的數據
                if("time".equals(cmd)){
                    writer.write(LocalTime.now()+"\n");
                    writer.flush();
                }
            }
        }
        sock.close();
        ss.close();
    }
}

先運行服務器端,再運行客戶端

socket

3. 總結:

TCP編程模型:編程語言

  • 客戶端使用Socket(InetAddress,port)打開Socket
  • 服務器用ServerSocket監聽端口
  • 服務器用accept接收鏈接並返回Socket
  • 雙方經過Socket打開InputStream/OutputStream讀寫數據
  • flush()用於強制輸出緩衝期
相關文章
相關標籤/搜索