TCP協(xié)議的通信實(shí)例

TCP協(xié)議的通信實(shí)例
馬克-to-win:我們首先給出一個(gè)最最簡(jiǎn)單的helloworld通信程序。讓大家體會(huì)一把兩臺(tái)機(jī)器的通信,大家之后就可以慢慢把它發(fā)展成為聊天程序。馬克-to-win:TCP通信有兩個(gè)類(lèi):1)ServerSocket:服務(wù)器用它監(jiān)聽(tīng)進(jìn)入的連接;2)Socket:雙方都用它初始一次連接。一旦客戶端申請(qǐng)建立一個(gè)連接,ServerSocket就會(huì)返回(通過(guò)accept()方法)一個(gè)對(duì)應(yīng)的服務(wù)器端的Socket,以便進(jìn)行直接通信。從此時(shí)起,我們就得到了一對(duì)真正的“Socket-Socket”連接,此時(shí)可以利用getInputStream()以及getOutputStream()從每個(gè)Socket產(chǎn)生對(duì)應(yīng)的 InputStream和OutputStream對(duì)象。之后,可按上章介紹的方法對(duì)類(lèi)進(jìn)行處理,就象原來(lái)對(duì)待其他任何流對(duì)象那樣。創(chuàng)建一個(gè) ServerSocket時(shí),只需為其賦予一個(gè)端口編號(hào)。但在創(chuàng)建一個(gè)客戶端 Socket時(shí),必須同時(shí)賦予IP以及要連接的端口。下面這對(duì)程序先運(yùn)行服務(wù)器程序,再運(yùn)行客戶端程序。馬克- to-win:馬克 java社區(qū):防盜版實(shí)名手機(jī)尾號(hào): 73203。




例:2.2.1(客戶端寫(xiě),服務(wù)器端讀)

import java.io.*;
import java.net.*;
public class TestMark_to_win {
    public static final int PORT = 4002;
    public static void main(String[] args) throws IOException {
        ServerSocket s = new ServerSocket(PORT);
        // Blocks until a connection occurs:
        System.out.println("我作為服務(wù)器,正等著你");
        Socket socket = s.accept();
        System.out.println("這句開(kāi)始打印不出來(lái)");
        InputStream in = socket.getInputStream();
        int i = in.read();
        System.out.println("Echoing: " + i);
        socket.close();
        s.close();
    }
}

以下是客戶端程序:

import java.net.*;
import java.io.*;
public class Test {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 4002);
        OutputStream out = socket.getOutputStream();
        out.write(97);
        socket.close();
    }
}

輸出結(jié)果:

我作為服務(wù)器,正等著你
這句開(kāi)始打印不出來(lái)
Echoing: 97




例:2.2.2(客戶端讀寫(xiě),服務(wù)器端也讀寫(xiě))(藍(lán)筆為比上一個(gè)程序多的部分)

import java.io.*;
import java.net.*;
public class TestMark_to_win {
    public static final int PORT = 4002;
    public static void main(String[] args) throws IOException {
        ServerSocket s = new ServerSocket(PORT);
        // Blocks until a connection occurs:
        System.out.println("我作為服務(wù)器,正等著你");
        Socket socket = s.accept();
        System.out.println("這句開(kāi)始打印不出來(lái)");
        InputStream in = socket.getInputStream();
// Blocks until a connection occurs:
        int i = in.read();
        System.out.println("服務(wù)器端反饋" + i);

        OutputStream out = socket.getOutputStream();
        out.write(98);
      
        socket.close();
        s.close();
    }
}

以下是客戶端程序:
import java.net.*;
import java.io.*;
public class Test {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 4002);
        OutputStream out = socket.getOutputStream();
        out.write(97);
      
        InputStream in = socket.getInputStream();
// Blocks until a connection occurs:
        int i = in.read();
        System.out.println("客戶端反饋" + i);
      
        socket.close();
    }
}

服務(wù)器輸出結(jié)果:

我作為服務(wù)器,正等著你
這句開(kāi)始打印不出來(lái)
服務(wù)器端反饋97



客戶端輸出結(jié)果:
客戶端反饋98


馬克-to-win:上一個(gè)程序是一個(gè)helloworld程序,所以我們寫(xiě)的故意很簡(jiǎn)單。下一個(gè)程序,我們寫(xiě)一個(gè)稍微有點(diǎn)兒實(shí)用性的,可以在客戶端和服務(wù)器端傳輸中文的。有一個(gè)重要的問(wèn)題就是:我們?yōu)槭裁从肂ufferedReader而B(niǎo)ufferedInputstream。因?yàn)?BufferedReader有一個(gè)方法是readLine,而在BufferedInputstream當(dāng)中,沒(méi)有這個(gè)方法。PrintWriter又是BufferedReader的一對(duì)天生好搭檔,里面有個(gè)方法:println。這樣客戶端和服務(wù)器端就可以每次都傳輸一行數(shù)據(jù),比上個(gè)例子每次傳輸一個(gè)字節(jié),方便的多了。




例:2.2.3(客戶端讀寫(xiě),服務(wù)器端也讀寫(xiě))

import java.io.*;
import java.net.*;
public class TestMark_to_win {
    public static final int PORT = 4002;
    public static void main(String[] args) throws IOException {
        ServerSocket s = new ServerSocket(PORT);
        System.out.println("服務(wù)器正等著");
        // Blocks until a connection occurs:
        Socket socket = s.accept();
        BufferedReader in = new BufferedReader(new InputStreamReader(
                socket.getInputStream()));
        /* autoFlush - A boolean; if true, the println() methods will flush the output buffer*/
        PrintWriter out = new PrintWriter((new OutputStreamWriter(
                socket.getOutputStream())), true);
        String str = in.readLine();
        System.out.println("Echoing: " + str);
        out.println(str + "回來(lái)從服務(wù)器");
        // Always close the two sockets...
        System.out.println("closing...");
        socket.close();
        s.close();
    }
}

下面是客戶端程序:
import java.net.*;
import java.io.*;
public class Test {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 4002);
        BufferedReader in = new BufferedReader(new InputStreamReader(
                socket.getInputStream()));
/* autoFlush - A boolean; if true, the println() methods will flush the output buffer*/
        PrintWriter out = new PrintWriter((new OutputStreamWriter(
                socket.getOutputStream())), true);
        out.println("你好 ");
        String str = in.readLine();
        System.out.println(str);
        System.out.println("closing...");
        socket.close();
    }
}

服務(wù)器輸出結(jié)果:
服務(wù)器正等著
Echoing: 你好
closing...

客戶端輸出結(jié)果:
你好 回來(lái)從服務(wù)器


closing...