基於Socket實現網絡編程

    Socket是網絡上兩個程序間雙向通訊的一端,它既可以發送請求,也可以接收請求,利用它可以方便的編寫網絡上數據的傳遞,在java中,有專門的類類處理用戶的請求和響應。利用Socket 類的方法,就可以實現兩臺計算機之間的通信,那麼怎麼利用socket進行網絡編程呢?我試試水~

網絡中的進程之間是如何進行通信的?

本地進程間通信(IPC)有很多種方法,簡而言之可以歸結爲以下四類:

  1. 消息傳遞(管道,FIFO,消息隊列);
  2. 同步(互斥量,條件變量,讀寫鎖,文件和寫記錄鎖,信號量);
  3. 內存共享(匿名的和具體的,線程等);
  4. 遠程過程調用(Solaris門和Sun RPC)。   

    那麼,對於網絡中的進程,如何實現通信呢?首先,我們要解決的是如何正確地唯一標識網絡中的進程,在本地環境中,我們可以通過進程PID來進行標識,但是在網絡中,不可以!但是網絡中的IP地址卻是唯一的可以標識一臺計算機,而位於傳輸層的“網絡+端口”可以唯一的標識主機中的應用程序(進程),這樣,可以利用IP地址+協議+端口就可以標識網絡中的進程啦!網絡中的進程就可以利用這三元組和其他進程之間進行通信了!

    使用TCP/IP協議的應用程序通常採用應用編程接口:UNIX  BSD的套接字(socket)和UNIX System V的TLI(已經被淘汰),來實現網絡進程之間的通信。就目前而言,幾乎所有的應用程序都是採用socket,而現在又是網絡時代,網絡中進程通信是無處不在,這就是爲什麼有人說“一切皆socket”。

 什麼是Socket?

       socket起源於Unix,而Unix/Linux基本哲學之一就是“一切皆文件”,都可以用“打開open –> 讀寫write/read –> 關閉close”模式來操作。我的理解就是Socket就是該模式的一個實現,socket即是一種特殊的文件,一些socket函數就是對其進行的操作(讀/寫IO、打開、關閉)。

    socket接口是TCP/IP網絡協議的API,socket接口設計者最先將接口放在UNIX操作系統裏面,如果瞭解UNix系統的輸入和輸出,Socket就很好理解了,網絡中的數據傳輸是一種特殊的I/O, Socket也是一種文件描述符,也具有一個類似於打開文件的函數調用socket(),該函數返回一個整形的socket描述符,隨後的連接建立,數據傳輸等操作都是通過該socket實現的。常用的socket類型有兩種,流式Socket和數據報式Socket(SOCK_DGRAM)。流式是一種面向連接的Socket,針對於面向連接的Tcp服務應用,而數據報式socket是一種面向非連接的UDP服務應用。

基於Socket的Java網絡編程

    Socket所支持的協議不光TCP/IP一種,因此兩者之間沒有必然的聯繫,在Java中,socket編程主要是基於TCP/IP協議的網絡編程。主要過程是:Server端Listen(監聽)某個端口是否有連接請求,Client端向Server端發出Connect(連接)請求,Server端向Client端發回Accept消息,這樣,一個連接就建立起來了,Server端和Client端都可以通過send,write等方法與對方進行通信。

對於一個功能齊全的Socket,都要包含以下基本結構,其工作過程包含以下四個基本步驟:

1,創建Socket;

2,打開連接到Socket的輸入輸出流;

3,按照一定的協議對Socket進行讀寫操作;

4,關閉socket。

簡單的例子:

客戶端程序:
package com.leetch.socket;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.io.StringReader;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class TestClient {
	public static void main(String arg[]) throws Exception{
		Socket tsocket = new Socket("127.0.0.1",4700);
			
		PrintWriter os = new PrintWriter(tsocket.getOutputStream());  
		//由socket對象得到輸出流,並構建PrintWriter對象
		
		BufferedReader bReader2 = new BufferedReader(
				new InputStreamReader(tsocket.getInputStream()));
		//由Socket對象得到輸入流,並構造相應的BufferedReader對象
		
		Reader reader = StringReader(textArea.getText().toString());
		BufferedReader bReader = new BufferedReader(reader);
		//由textarea構造bufferedreader對象
		
		String readline = null;
		readline = bReader.readLine();
		
		while(!readline.equals("bye")){  //結束判斷標誌
			os.println(readline);  //把文本域裏面的內容寫到server端
			os.flush();
			System.out.println("Client:"+readline);
			System.out.println("Server:"+bReader2.readLine());
			readline = bReader.readLine();
		}
		os.close();
		bReader2.close();
		tsocket.close();
	}

	private static Reader StringReader(String string) {
		// TODO Auto-generated method stub
		return null;
	}
}

服務器端代碼:
package com.leetch.socket;
import java.io.*;
import java.net.*;
import java.applet.Applet;


public class TServer{
	public static void main(String args[]) {
		try{
			ServerSocket server=null;
			server=new ServerSocket(4700);
			System.out.println("正在監聽端口...");  //創建一個ServerSocket在端口4700監聽客戶請求
			
			Socket socket=server.accept();   //創建一個socket,監聽4700端口
			
			//由Socket對象得到輸入流,並構造相應的BufferedReader對象
			BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
			
			//由Socket對象得到輸出流,並構造PrintWriter對象
			PrintWriter os=new PrintWriter(socket.getOutputStream());


			//由系統標準輸入設備構造BufferedReader對象
			BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));


			System.out.println("Client:"+is.readLine());
			//在標準輸出上打印從客戶端讀入的字符串


			String readline;
			readline=sin.readLine();
			
			while(!readline.equals("quit")){   //終止條件
				os.println(readline);   //向客戶端返回請求值,及時刷新
				os.flush();     
				System.out.println("Server響應:"+readline);		//在系統標準輸出上打印讀入的字符串
				System.out.println("Client請求:"+is.readLine());//讀取client請求,並顯示
				readline=sin.readLine();  
			}
			System.out.println("已中斷連接...");
			os.close();
			is.close(); 
			socket.close();
			server.close();
		}catch(Exception e0){
			e0.printStackTrace();
		}
	}
}
測試結果正確,客戶端和服務器可以互通消息!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章