JAVA學習筆記(初級)--網絡編程

1 網絡編程基礎html

本節主要總結基本概念:IP地址,端口,套接字,數據包,Internet協議java

  • IP地址:一個32位(ipv4)或者64位(ipv6)數的標識,ip地址是一個接入一個網絡的計算機的惟一標識,能夠經過IP地址。接入多個網絡的計算機能夠擁有多個IP,稱爲多宿主機。java能夠經過InetAddress類描述IP地址。 InetAddress類的方法
    getLocalHost() 獲取主機的IP地址
    getByName() 經過主機名獲取IP
    getAllByNaeme() 獲取多宿主機的所有IP
    getAddress() 獲取用一個字節數組成的IP
    getHostName() 得到某個IP對應的主機名

    實例很簡單就再也不說明。編程

  • 端口:端口是計算機輸入輸出的接口,例如串口(物理端口)。計算機鏈接網絡須要一個邏輯接口,這個接口便是端口。端口號屬於TCP/IP協議一部分。1024之內的端口通常有特殊用途,不建議調用。
  • 套接字:形象的表示爲一個插座,須要須要用電是必須使用插座,一樣兩臺計算機經過網絡進行鏈接時也必須使用套接字。套接字機制是TCP/IP協議的通訊機制。java用Socket和ServerSocket兩個類實現套接字(能夠用java裏的實現理解套接字,但套接字的實現並不止java的實現)。使用套接字進行鏈接通訊,須要使用到前面講到的IP地址和端口。後面會詳細介紹。
  • 數據包:java裏的Datagram類實現了數據包。數據包的使用狀況是在使用UDP非鏈接協議進行通訊的時候,即通訊前不先進行鏈接,而是將通訊信息(即數據包的數據,數據長度,來源主機IP和目的主機IP等)封裝在數據包中。
  • Internet協議:網絡協議是描述數據交換時所遵循的規則和數據格式,即要傳輸的數據類型,如何解釋數據及怎樣請求傳輸數據。以下是經常使用協議及通常綁定的端口 經常使用網絡協議及綁定端口號
    Echo 將所用東西彈回來 7
    Discard 丟棄所用的東西 9
    Daytime 發送日期和時間 13
    Ftp 文件傳輸協議 21
    Telnet 終端協議 23
    Smtp 簡單郵件傳輸協議 25
    Finger 顯示用戶信息協議 79
    Http 超文本傳輸協議 80
    Pop3 郵件協議 110
    Nntp 網絡新聞協議 119
    Imap 管理服務器郵件協議 143
    Talk 與另外用戶交談協議 517
    Kerberos 安全服務協議 750

    其中比較重要的有HTTP,FTP,AMTP,POP。數組

 2 URL類機器使用安全

2.1 URL類:統一資源定位器服務器

URL是網絡資源的引用,理解爲網絡資源地址(資源包括HTML頁面文件,圖像文件,音頻文件視頻文件等),有了地址即可以經過地址去獲取,只是目的。URL的通用格式:網絡

<PROTACOL>://<HOSTNAME:PORT>/<PATH>/<FILE>
  • PROTOCOL:即前面講到的協議;
  • HOSTNAME:PORT:即主機名和端口號;
  • PATH:路徑;
  • FILE:文件名;

2.2 URL類的使用:訪問www資源框架

  • 創建URL對象:使用絕對地址和相對地址(推薦)
    //創建一個絕對URL對象
    URL root=new URL("http://www.yahoo.com/");
    //使用絕對URL對象創建 另外一個相對URL對象
    URL target=new URL(root,"index.html");

     

  •  經過調用URL對象的getContent()/openStream()方法讀取內容
    Object content=target.getContent();
    //或者
    //DataInputStream in=new DataInputStream(target.openStream());

     

  • 使用URL的openConnection()創建鏈接,返回URLConnection類的一個對象,經過這個對象進行IO流操做。
    URL url=new URL("http://www.yahoo.com/");
    URLConnection connection=yahoo.openConnection();//創建鏈接
    DataInputStream in=new DataInputStream(connection.getInputStream());//使用流的方式從鏈接中獲取數據

    注意:訪問國外主機有些須要設置代理主機,不然會報異常:unknownhostexception。socket

 3 Socket 和ServerSocket類函數

Socket類用於網絡上的進程通訊,調用構造方法便可建立一個鏈接,以後即可以經過這個鏈接進行數據傳輸

Socket對象的建立以下:客戶端須要提供目標主(服務器的IP),端口號

Socket socketname=new Socket(hostname,portnum);

JDK中Socket源碼:

public class Socket extends Object{
     public Socket(String host,int port)throws UnknownHostException,IOException;
     public Socket(String host,int port,boolean stream)throws UnknownHostException,IOException;
     public Socket(InetAddress address,int port)throws IOException;
     public Socket(InetAddress address,int port,boolean stream)throws IOException;
     public void close()throws IOException;
     public InetAddress getInetAddress();
     public InetAddress getLocalAddress();
     public InputStream getInputStream();
     public OutputStream geOutputStream();
     public int getPort();
     public int get LocalPort();
     public String toString();
}

由此能夠知道Socket的使用。

  • 客戶端編程

如下是兩個書上的使用Socket的例子源碼:

package javatest;
import java.net.*;
import java.io.*;
public class WebConnect {
	public static void main(String args[]){
		try{
			Socket connection=new Socket("127.0.0.1",8002);//此處的ip地址修改爲本身的ip地址
			System.out.println(connection.getLocalAddress());
			System.out.println(connection.getLocalPort());
			System.out.println(connection.getInetAddress());
			System.out.println(connection.getPort());
			connection.close();
		}catch(UnknownHostException uhe){
			System.err.println("unknow");
		}catch(IOException ioe){
			System.err.println(ioe);
		}
	}
}
package javatest;
import java.net.*;
import java.io.*;
public class EchoClient {
	public static void main(String args[]){
		try{
			Socket connection=new Socket("127.0.0.1",7);//此處的ip地址修改爲本身的ip地址
			DataInputStream in=new DataInputStream(connection.getInputStream());
			DataOutputStream out=new DataOutputStream(connection.getOutputStream());
			String line=new String("");
			while(!(line.toUpperCase().equals(".QUIT"))){
				System.out.println("Enter String:");
				line=readString();
				System.out.println("\tSending to server...:");
				out.writeUTF(line);
				System.out.println("\tWaiting for server to answer...:");
				line=in.readUTF();
				System.out.println("\treceived:"+line);
			}
			in.close();out.close();
			connection.close();
		}catch(UnknownHostException uhe){
			System.err.println("unknow");
		}catch(IOException ioe){
			System.err.println(ioe);
		}
	}
	public static String readString(){
		String string=new String();
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		try{
			string=in.readLine();
		}catch(IOException ioe){
			System.err.println(ioe);
			System.exit(-1);
		}
		return string;
	}
}

代碼很簡單,不介紹

  • 服務器端編程

 客戶端使用Socket創建一個鏈接,服務器端要先使用ServerSocket對象定義監聽的端口,而後當有有鏈接請求時創建一個Socket鏈接(調用ServerSocket對象的accept方法返回的Socket對象),經過這個鏈接來傳輸數據。通訊過程用書上的圖表示以下(畫圖比較麻煩因此直接使用手機圖片)

ServerSocket的使用以下:(要給定監聽的端口)

ServerSocket connection=new ServerSocket(port);

ServerSocket類的JDK源碼:

public class ServerSocket extends Object{
     public ServerSocket(int port) throws IOException;
     public ServerSocket(int port,int backLogQueueSize)throws IOException;
     public Socket accept()throws IOException;
     public void close()throws IOException;
     public InetAddress getInetAddress()throws IOException;
     public int getLocalPort();
     public String toString();
}

一樣是很直觀即可以知道如何使用。如下是服務器端的一些例子。

package javatest;
import java.net.*;
import java.io.*;
public class EchoServer {
	private static boolean running=true;
	public static void main(String args[]){
		try{
			ServerSocket server=new ServerSocket(8001);
			System.out.println("Server start on "+server.getLocalPort());
			while(running){
				Socket connection =server.accept();
				DataInputStream in=new DataInputStream(connection.getInputStream());
				DataOutputStream out=new DataOutputStream(connection.getOutputStream());
				String line=new String("");
				try{
					while(!line.equalsIgnoreCase(".QUIT")){
						//System.out.println("Enter String:");
						line=in.readUTF();
						System.out.println("\treceived:"+line);
						//System.out.println("\tSending to server...:");
						if(line.toUpperCase().equals(".SHUTDOWN")){
							running=false;
							line=".QUIT";
						}
						out.writeUTF(line+"nihao!");
						//System.out.println("\tWaiting for server to answer...:");
						
					}
					in.close();out.close();server.close();
					connection.close();
				}catch(IOException ioe){
					System.out.println("connection is closed");
				}
				
			}
			System.out.println("server is closed");
		}catch(UnknownHostException uhe){
			System.err.println("unknow");
		}catch(IOException ioe){
			System.err.println(ioe);
		}
	}
}

 書上還對本程序進行了優化,即將接收到鏈接請求以後的創建請求的實現交給一個線程,以及解決程序不能中止的問題,實現起來也就是對收到的流進行驗證,當等於特定字符串時結束while循環,關閉流對象和鏈接,以及實現線程類等。

4 基於Datagram的客戶端和服務器端編程

前面講到的通訊都是在鏈接的基礎上實現的,即TCP通訊協議的基本實現,使用Datagram進行通訊則是非鏈接的,即將使用數據包,並將數據,數據長度,來源主機IP,目標主機IP封裝在數據包中(Datagram對象),並將數據包發送出去,數據包按照傳輸協議傳輸,直到找到目標主機,整個通訊過程要深刻學習能夠查找相關書籍或教程,不講(由於我也不會哈哈)。Datagram的傳輸必須依賴於DatagranSocket類和DatagramPacket。

DatagramPacket的構造方法:用來打包數據

public DatagramSocket(byte[] buff,int length,InetAddress iaddr,int port);

DatagramSocket的構造函數:

public DatagramSocket();//在本地主機上任何一個端口建立Socket
public DatagramSocket(int port);//在指定端口建立Socket

如下是一個利用DatagramSocket來查詢端口的使用狀況的應用源碼:

package javatest;
import java.net.*;
public class UDPScan {
	public static void main(String args[]){
		for(int port=1;port<65535;port++){
			try{
				DatagramSocket server=new DatagramSocket(port);
				server.close();
			}catch(SocketException se){
				System.out.println("this is a server in "+port+".");
			}
		}
	}
}

如下是Datagram實現的客戶端服務器端通訊例子

//客戶端源碼
package javatest;
import java.io.IOException;
import java.net.*;
public class UDPClient {
	public static void main(String args[]){
		try{
			DatagramSocket sendSocket=new DatagramSocket();
			String send=new String("hello,jfchen!nihao");
			byte[] databyte=send.getBytes();
			DatagramPacket sendPacket=new DatagramPacket(databyte,databyte.length,InetAddress.getByName("127.0.0.1"),8001);
			sendSocket.send(sendPacket);
			System.out.println("data start sending,hello jfchen");
			System.out.println(send);
		}catch(SocketException se){
			se.printStackTrace();
			System.exit(1);
		}catch(IOException ioe){
			System.out.println("網絡通訊出錯,問題爲:"+ioe.toString());
		}
	}
}



//服務器端
package javatest;
import java.io.IOException;
import java.net.*;
public class UDPServer {
	public static void main(String args[]){
		try{
			DatagramSocket receiveSocket=new DatagramSocket(8001);
			byte []bytes=new byte[1024];
			DatagramPacket receipacket=new DatagramPacket(bytes,bytes.length);
			System.out.println("send now");
			while(true){
				receiveSocket.receive(receipacket);
				String hostName=receipacket.getAddress().toString();
				System.out.println("data come from host"+hostName+"port"+receipacket.getPort());
				String s=new String(receipacket.getData(),0,receipacket.getLength());
				System.out.println("data receive:"+s);
			}
		}catch(SocketException se){
			se.printStackTrace();
			System.exit(1);
		}catch(IOException ioe){
			System.out.println("there is problem with network:"+ioe.toString());
		}
	}
}

發送端的主要框架:

byte[] data=new byte[1024];//要傳輸的數據
DatagramSocket dst=new DatagramSocket();//客戶端不用指定端口
InetAddress destip=InetAddress.getByName(null);//此處改成目標主機ip
DatagramPacket dpt=new DatagramPacket(data,data.length,destip,8080);//數據打包,此處端口8080能夠自定義
dst.send(dpt);//調用Socket的send方法發送數據

服務器端主要框架:

DatagramSocket dst=new DatagramSocket(8080);//能夠自定義端口號
DatagramPacket dpt;
dpt=dst.receive(dpt);//接收數據
String string=new String(dpt.getData());//將數據轉成字符串格式

5  並行計算

最後來簡單認識一下並行計算,書上又一個矩陣乘法的並行計算例子,這裏就不貼代碼了。

實現基於客戶/服務模式的分佈應用的機制不少,這些應用能夠分解成多個客戶端和多個服務器端應用,分佈在不一樣額計算機上運行。在一個用戶要求多個服務器爲其提供服務的狀況下,很適合用「工做者-管理者」分佈模型上實現。在這種分佈模型下,並行應用能夠這樣設計:一個大的應用分解成若干個小的應用,這些小應用能夠分別由多個服務器爲其提供服務,這樣應用能夠同時運行,同時進行計算,當獲得計算結果後返回給客戶機,客戶機手機結果後再輸出給客戶。模型用圖來表示以下:

並行計算的實現框架:

  • 線程
  • IO流
  • 客戶端框架
  • 服務器端框架

 具體的就不說了,關於並行計算,有想深刻研究這方面的建議去找相關教程,好像社會需求量也不低,並且也是一門很講技術的活。

最後說說本身寫這篇文章的體會吧,首先是不記得多久以前了看過課本,就是大體瞭解了一下本章的內容而已,以致於在我內心只有一個很模糊的印象,前些日子重翻這本書,再學習一邊,並寫了一些筆記放在開源中國,前幾天學到網絡編程這章,先是再看了一遍書,看了源碼,以及實現了一些書上了例子,第一次用CMD進行編譯調試運行,以爲學到不少東西。以後再是昨天動手寫這篇博客,也是寫的很淺(原諒我這個菜鳥),到晚上十點多的時候,放鬆一下又怕學校斷網寫到一半就發佈了,沒想到一個小時不到就有6個閱讀量了,今天早上起來一看已經21個了,還有兩我的收藏了,對於別的技術大牛的博文而言可能根本不算什麼,可是對於我來講,這是一種頗有力量的鼓勵。因此後面又把昨天沒寫完的補了上去,最後囉嗦幾句。謝謝你們,我也會繼續努力,爭取能總結出愈來愈有水平對你們有幫助的東西。

相關文章
相關標籤/搜索