2011年3月4日 星期五

Java 網路程式 - Client/Server 通訊實作

本篇介紹以 Java Socket 實做 Client/Server 的簡單通訊實做

主要以 Socket 實現一個Server 端來接收 Client 的連線  往後在介紹更多的 Client/Server 的通訊方法

首先先說明常用於網路串流的 DataInputStream 和 DataOutputStream

不過你也是可以利用其他的串流類別,如: PrintWriter

通常再某一端(Client) 如要讀取Server的資料或是傳送資料給Server 時

都需要取得串流在能夠讀取或是寫入,而都是以

java.net.SocketgetInputStream()getOutputStream() 這兩個方法來取得串流

並加載於 DataInputStream 或是 DataOutputStream 上,例如以下所示

DataInputStream datain = new DataInputStream(socket.getInputStream());

以下是 DataOutputStream 常用的寫入串流方法,如下


voidwriteBoolean(boolean v)
writeByte(int v)
writeChar(int v)
writeDouble(double v)
writeInt(int v)
writeUTF(String str)   //常用


以下是 DataInputStream 長用的讀取串流方法,如下


byte
boolean
char
double
String
String
readByte()
readBoolean()
readChar()
readDouble()
readLine()
readUTF() 

以下來看一下 Client 的程式
import java.io.*;
import java.net.*;
public class echoClient{
    public echoClient(int port)
    {
        try{
            Socket client = new Socket("xxx.xxx.x.xxx", port); //這裡填入Server端的IP位置
            System.out.println("----  connect to xxx.xxx.x.xxx  ----");
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));  //鍵盤輸入
            DataOutputStream out = new DataOutputStream(client.getOutputStream());  
            DataInputStream datain = new DataInputStream(client.getInputStream());

            String input = in.readLine(); //由鍵盤讀取一段資料
            out.writeUTF(input);   //並將資料寫入到串流(即傳送給 Server)
            System.out.println(datain.readUTF());   //由 Server 端讀取Server傳過來的資料
            client.close(); 
        }catch(Exception e){
            System.out.println(e.getMessage());
            System.exit(-1);
        }
    }
    public static void main(String[] args) 
    {
        int port = 0;
        if(args.length < 1)  //需輸入 Server 端的埠號
        {
            System.out.println("Usage: java echoClient [port]");  
            System.exit(1);
        }else{
            port = Integer.parseInt(args[0]);
            echoClient client = new echoClient(port);
        }
    }
}

以下為 Server 端的程式
import java.io.*;
import java.net.*;
public class echoServer
{
    public echoServer(int port)
    {
        try{
            ServerSocket server = new ServerSocket(port);
            System.out.println("start to waiting...");
            Socket clientSocket = server.accept();  //接收一個 client 連線
            java.util.Date currentDate = new java.util.Date();
            /*** 印出 client 的資料 ***/
            System.out.println("-----  Accept a client  -----");
            System.out.println("Clinet IP: " + clientSocket.getInetAddress().getHostAddress());//Client IP
            System.out.println("Client Port: " + clientSocket.getPort());  //Client 埠號
            System.out.println("connect date: " + currentDate);    //目前時間
            this.process(clientSocket);
            clientSocket.close();
        }catch(IOException e){
            System.out.println("Could not listen on port:" + port);
            System.exit(-1);
        }
    }
    public void process(Socket client)
    {
        try{
            DataOutputStream out = new DataOutputStream(client.getOutputStream());
            DataInputStream in = new DataInputStream(client.getInputStream());
            String userInput = in.readUTF();   //讀取 Client 傳送過來的資料
            System.out.println("receive from client : " + userInput);
            out.writeUTF("Server has a echo : " + userInput);   //將該資料產生 echo 並回傳
        }catch(IOException e){
            System.out.println("Client out");
        }
    }
    public static void main(String[] args)
    {
        int port;
        if(args.length < 1)  
        {
            System.out.println("Usage: java Server_7 [port]");  //建立一個 Server 須要一個埠號
            System.exit(1);
     }
        try{
            port = Integer.parseInt(args[0]);
            echoServer s = new echoServer(port);
        }
        catch(NumberFormatException e){
            System.out.println("Port is Integer!!");
        }
    }
}

以上程式應該可以發現 一次只能一個連線

要讓一個 Server 接收多個請求並互相溝通

需要將

Socket clientSocket = server.accept(); 至於回圈內

再加上執行緒的控制方可達成,這個之後再介紹吧

沒有留言:

張貼留言