2015年5月24日 星期日

[Java]Socket

認識SOKET

Socket Library是BSD UNIX的一個API (Application Programming Interface),


Socket兩個互相溝通的程序(process)之間的任一端點。

此兩個process可同屬一電腦系統之內,或分屬於兩個不同的電腦系統透過網路來溝通。


使用目的:網路應用程式設計者不需處理網路下層(傳輸層、網路層)的工作,而專注於其本身

(應用層)的程式設計。

























JAVA 在使用SOCKT 時,有二種常用的方式

1.TCP: 它就像是雙掛號,對方沒有收到就會不斷嘗試再送給對方,

直到使用者中止或是俞時。



2.UDP : UDP則是類似一般的平信,通常都會送達,但還是會有不見的時候,但成本便宜,
     
                  無須等待對方回應即可繼續傳送。
     
               (看過海角七號就知道)


Java TCP 的流程圖

伺服端ServerSocket 等待使用者的Socket來做連線,並取得輸出入通道。
























MyServerSocket.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServerSocket {
        //宣告區
	ServerSocket server;
	ObjectInputStream in;
	ObjectOutputStream out;
	BufferedReader buffer;
	Thread inputThread;
	Thread recThread;
	boolean isClose = false;
	Socket client;
	public MyServerSocket() {
		try {
                      //ServerSocket Listen 在本機的5678 port
			server = new ServerSocket(5678);
                      //輸出己啟動伺服器資訊
			System.out.println("伺服器啟動於 : "
					+ InetAddress.getLocalHost().getHostAddress() + ":"
					+ server.getLocalPort());
                         //把連線過來的Client端交由另一個socket處理
			client=server.accept();
                    //輸出訊息己有使用者連進來
			System.out.println("Client is connected");
                      //將Server端的標準輸出入設為鍵盤
			buffer=new BufferedReader(new InputStreamReader(System.in));
                      //取得與此使用者的輸出管道
			out=new ObjectOutputStream(client.getOutputStream());
                       //取得與此使用者的輸入管道
			in=new ObjectInputStream(client.getInputStream());
			
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		//用一個執行序負毒處理接收到的訊息
		recThread = new Thread(new Runnable() {

			@Override
			public void run() {
				recMessage();
			}
		});
                //啟動接收訊息執行序
		recThread.start();
                //使用一個執行序來處理Server端的鍵盤輸入
		inputThread = new Thread(new Runnable() {

			@Override
			public void run() {
				keyin();

			}
		});
                //啟動server端輸入執行序
		inputThread.start();
	}
      //Server端鍵盤處理函式
	private void keyin() {
		try {
			String line;

			while (!(line = buffer.readLine()).equals("-1")) {
				System.out.println("傳送:" + line);
				write(line);
				Thread.sleep(100);

			}
			isClose = true;
			close();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
        //接收訊息處理函式
	private void recMessage() {
		String recText = "";
		while (!isClose) {
			try {

				recText = in.readUTF();
				System.out.println("接收:" + recText);
				Thread.sleep(100);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
        輸出資料到client端函式
	private void write(String text) {
		try {
			out.writeUTF(text);
			out.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void close() {
		try {

			recThread.interrupt();
			inputThread.interrupt();
			out.flush();
			out.close();
			in.close();
			client.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	//主程式
	public static void main(String arg[])
	{
		new MyServerSocket();
	}
}


MySocket.java
import java.io.IOException;
import java.net.Socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.UnknownHostException;

public class MySocket {

	Socket client;

	ObjectInputStream in;
	ObjectOutputStream out;
	BufferedReader buffer;
	Thread inputThread;
	Thread recThread;
	boolean isClose = false;

	public MySocket() {
		String ServerIP = "127.0.0.1";
		try {
			client = new Socket(ServerIP, 5678);
			in = new ObjectInputStream(client.getInputStream());
			out = new ObjectOutputStream(client.getOutputStream());
			buffer = new BufferedReader(new InputStreamReader(System.in));
		} catch (IOException e) {
			e.printStackTrace();
		}

		recThread = new Thread(new Runnable() {

			@Override
			public void run() {
				recMessage();
			}
		});

		recThread.start();

		inputThread = new Thread(new Runnable() {

			@Override
			public void run() {
				keyin();

			}
		});

		inputThread.start();
	}

	private void keyin() {
		try {
			String line;

			while (!(line = buffer.readLine()).equals("-1")) {
				System.out.println("傳送:" + line);
				write(line);
				Thread.sleep(100);

			}
			isClose = true;
			close();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void recMessage() {
		String recText = "";
		while (!isClose) {
			try {

				recText = in.readUTF();
				System.out.println("接收:" + recText);
				Thread.sleep(100);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private void write(String text) {
		try {
			out.writeUTF(text);
			out.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void close() {
		try {

			recThread.interrupt();
			inputThread.interrupt();
			out.flush();
			out.close();
			in.close();
			client.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public static void main(String args[]) {
		new MySocket();
	}
}



Java UDP 流程圖



















直接傳送過去,並沒有任何的驗證機制。

UDPServer.java
import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

import java.net.SocketException;

import java.net.UnknownHostException;



public class UDPServer {

	boolean isClose = false;

	byte[] Bytebuffer = new byte[65507];

	DatagramPacket dp = new DatagramPacket(Bytebuffer, Bytebuffer.length);

	DatagramSocket ds;

	Thread recThread;



	public UDPServer() {

		try {



			ds = new DatagramSocket(5678);

			System.out.println("伺服器啟動於 : "

					+ InetAddress.getLocalHost().getHostAddress() + ":"

					+ ds.getLocalPort());

			recThread = new Thread(new Runnable() {



				@Override

				public void run() {

					recMessage();

				}

			});



			recThread.start();



		} catch (SocketException e) {

			e.printStackTrace();

		} catch (UnknownHostException e) {

			e.printStackTrace();

		}

	}



	private void recMessage() {

		try {

			String msg = "";

			while (!isClose) {

				ds.receive(dp);

				msg = new String(dp.getData(), 0, dp.getLength());

				System.out.println("傳來的訊息 : " + msg);

				Thread.sleep(100);

			}

		} catch (IOException e) {

			// TODO Auto-generated catch block

			e.printStackTrace();

		} catch (InterruptedException e) {

			// TODO Auto-generated catch block

			e.printStackTrace();

		}

	}

	public static void main(String args[]) {

		new UDPServer();

	}



}


UDPClient.java

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

import java.net.SocketException;

import java.net.UnknownHostException;



public class UDPClient {

	DatagramPacket dp;	

	DatagramSocket ds;

	Thread inputThread;

	BufferedReader buffer;

	public UDPClient() {

		System.out.println("請輸入要傳送的訊息 : ");

		String msg = "Key in";

		buffer = new BufferedReader(new InputStreamReader(System.in));

		try {

			ds=new DatagramSocket();

		} catch (SocketException e) {

			// TODO Auto-generated catch block

			e.printStackTrace();

		}

		inputThread = new Thread(new Runnable() {



			@Override

			public void run() {

				keyin();

			}

		});



		inputThread.start();

	}



	private void keyin() {

		try {

			String line;



			while (!(line = buffer.readLine()).equals("-1")) {

				System.out.println("傳送:" + line);

				write(line);

				Thread.sleep(100);

			}

		} catch (IOException e) {

			

			e.printStackTrace();

		} catch (InterruptedException e) {			

			e.printStackTrace();

		}

	}



	private void write(String text) {

		try {

			dp = new DatagramPacket(text.getBytes(), text.getBytes().length,

					InetAddress.getByName("127.0.0.1"), 5678);



			ds.send(dp);

		} catch (UnknownHostException e) {

			// TODO Auto-generated catch block

			e.printStackTrace();

		} catch (IOException e) {

			// TODO Auto-generated catch block

			e.printStackTrace();

		}

	}

	

	public static void main(String args[])

	{

		new UDPClient();

	}

}



參考資料:

https://sites.google.com/a/mis.nsysu.edu.tw/cheng-shi-zi-xun-wang/java-jin-jie-pian/wang-lu-pian/1-shen-me-shisocket

部份圖片來自網路,若有侵權請來信告知。

沒有留言:

張貼留言