java網(wǎng)絡(luò)編程基本知識
java網(wǎng)絡(luò)編程的基本知識不少,下面yjbys小編為大家分享最新最全java中網(wǎng)絡(luò)程序基本知識,歡迎參考學(xué)習(xí)!
網(wǎng)絡(luò)基本知識:
在java中網(wǎng)絡(luò)程序有兩種協(xié)議:TCP和UDP,TCP通過握手協(xié)議進(jìn)行可靠的連接,UDP則是不可靠連接。
IP地址:用于標(biāo)記一臺計算機(jī)的身份證。
IP地址由網(wǎng)絡(luò)地址(確定網(wǎng)絡(luò))和主機(jī)地址(網(wǎng)絡(luò)中的主機(jī))組成。
子網(wǎng)掩碼:為了區(qū)分網(wǎng)絡(luò)地址和主機(jī)地址。
IP地址分為A類地址、B類地址、C類地址(常用)、D類地址、E類地址。
127.0.0.1(localhost)是本機(jī)地址。
IPV4和IPV6
IPV4使用4個十進(jìn)制數(shù)表示,即32位二進(jìn)制。
SMTP是簡單郵件傳輸協(xié)議,端口號是25.
telnet用于連接遠(yuǎn)程計算機(jī)或者因特網(wǎng)計算機(jī)提供的服務(wù)。每個服務(wù)都會設(shè)定一個端口。
給出類似 telnet ip port 即可和特定的服務(wù)進(jìn)行通信
如果要連接因特網(wǎng)的服務(wù),不僅要給出端口,還要給出計算機(jī)的名稱,只有給出IP地址和端口號時,才能夠請求服務(wù),并接收到應(yīng)答。
URL和URI
URI:統(tǒng)一資源標(biāo)識符,用于標(biāo)識一個web資源,包含了兩個部分。
(1)URL:統(tǒng)一資源定位符。能夠精確的定位數(shù)據(jù)的URI
(2)URN:統(tǒng)一資源名稱。除了URL的URI
在java中URI和URL是分開的'兩個類,URI類專門用于解析,URL用于通信。
URL
1.URI分類
絕對和相對:
(1)絕對URI是指有確定的協(xié)議。比如http,ftp。后面以/進(jìn)行分隔
(2)相對URI是沒有scheme的。
透明和不透明:
(1)不透明URI是不能夠被解析的URI。不透明URI是絕對URI。scheme后面的部分不是以/進(jìn)行分割。
分層和不分層:
(1)分層是絕對透明URI或相對URI。
所有的網(wǎng)頁端口都是80.
2.URI的作用:
(1)解析
URI的格式:
[scheme:]scheme-specific-part[#fragment]
scheme表示用的協(xié)議,可以是http\https\ftp\file等。
scheme-specific-part是其余部分。
進(jìn)一步細(xì)分:
[scheme:][//authority][path][?query][#fragment]
常用方法:
getScheme()獲得scheme;
getSchemeSpecificPart()
getPath()
getAuthority()
(2)相對標(biāo)識符和絕對標(biāo)識符的轉(zhuǎn)換
resolve和relative函數(shù)。
URL和URLConnection
URL的作用
1.如果想要獲取某個網(wǎng)頁的html源代碼,比如http://blog.csdn.net/xiazdong 則只需要:
(1)URL url = new URL("http://blog.csdn.net/xiazdong");
(2)Scanner in = new Scanner(url.openStream());
即可.
2.獲取消息頭信息
URLConnection connection = url.openConnection();
connection.getHeaderFields()返回一個Map>
connection.getContentLength();
connection.getContentType();
connection.setDoOutput(true)獲得輸出流
connection.getOutputStream();
connection.getInputStream();
在網(wǎng)頁中如果要提交數(shù)據(jù)給web服務(wù)器,通常要把數(shù)據(jù)發(fā)送給web服務(wù)器,然后web服務(wù)器委派一個腳本對數(shù)據(jù)進(jìn)行處理,返回一個相應(yīng)。
通常發(fā)送數(shù)據(jù)的方法有兩種:get和post。
(1)get方法是直接把數(shù)據(jù)跟在url的后面,以name=value進(jìn)行傳輸,
每個數(shù)據(jù)之間用&進(jìn)行分割,value中的空格用+替換,非字母數(shù)字用%替換,并后跟兩個16進(jìn)制數(shù),這種編碼方式稱為URL編碼。URLEncoder和URLDecoder
(2)post方法是通過URLConnection發(fā)送給服務(wù)器,編碼方式和get一樣。URLEncoder.encode(VALUE,"UTF-8");
一般在傳輸中文時會運(yùn)用編碼和解碼。
示例:通過URLEncoder和URLDecoder編碼和解碼
略
InetAddress 根據(jù)域名得到IP地址或名稱
沒有構(gòu)造方法,通過:
(1)InetAddress i1 = InetAddress.getByName(String)返回一個InetAddress實(shí)例。
(2)如果一個地址有多個ip地址,比如google,有3個ip地址,就調(diào)用InetAddress[] i2 = InetAddress.getAllByName(String);
InetAddress.getLocalhost()獲得本機(jī)的InetAddress實(shí)例。
Socket(TCP)
Socket是一個用于機(jī)器之間通信的類。
Socket客戶端:
(1)Socket s = new Socket(ip,port);打開一個套接字,發(fā)送請求
(2)InputStream istream = s.getInputStream();接收數(shù)據(jù)
(3)OutputStream ostream = s.getOutputStream();發(fā)送數(shù)據(jù)
需要用PrintWriter和Scanner進(jìn)行包裝,并且注意PrintWriter的自動緩沖。
Socket服務(wù)器:注意多個客戶端同時訪問服務(wù)器的問題:多線程
(1)ServerSocket server = new ServerSocket(port);創(chuàng)建一個端口
(2)Socket s = server.accept(); 只有當(dāng)有客戶端請求并連接,函數(shù)才會返回
(3)InputStream istream = s.getInputStream();接收數(shù)據(jù)
(4)OutputStream ostream = s.getOutputStream();發(fā)送數(shù)據(jù)
需要用PrintWriter和Scanner進(jìn)行包裝,并且注意PrintWriter的自動緩沖。
我們在使用PrintWriter時需要使用println()函數(shù);
當(dāng)服務(wù)器或客戶端任意一方請求結(jié)束通信,則立刻停止。
問題1:在套接字中會發(fā)生阻塞的地方:
(1)實(shí)例化Socket時,會阻塞。
(2)在in.nextLine()類似操作時會阻塞。
解決方法:
(1)對于第一個問題,解決方法:
Socket s = new Socket();建立無連接socket
s.connect(new InetSocketAddress(host,port),timeout);設(shè)置超時。
(2)對于第二個問題,解決方法是設(shè)置s.setSoTimeout(long)設(shè)置超時時間
問題2:當(dāng)客戶端想要關(guān)閉套接字時,但卻不能確定服務(wù)器是否還在發(fā)送數(shù)據(jù),但是只要一關(guān)閉就立刻斷開。
解決方法:
socket.shutdownOutput()關(guān)閉輸出流
socket.shutdownInput()關(guān)閉輸入流
綜合代碼舉例:實(shí)現(xiàn)一個簡單的對等通信程序,通過多線程,一個線程接收數(shù)據(jù),一個線程發(fā)送數(shù)據(jù)。
用戶1:
[java] view plain copy
import java.util.*;
import java.io.*;
import java.net.*;
public class Client{
public static void main(String[]args)throws Exception{
Socket s = new Socket("localhost",8819);
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
Thread t = new Thread(new Receive(s));
t.start();
//以下代碼用于發(fā)送數(shù)據(jù)
Scanner in = new Scanner(System.in);//鍵盤輸入
while(in.hasNextLine()){ //一直不斷
out.println(in.nextLine()); //發(fā)送鍵盤輸入數(shù)據(jù)
}
}
}
class Receive implements Runnable //這個類用于接收數(shù)據(jù)
{
private Socket s;
public Receive(Socket s)
{
this.s = s;
}
public void run()
{
try{
Scanner in = new Scanner(s.getInputStream()); //in:接收數(shù)據(jù)
String str = null;
while(true)
{
str = in.nextLine();
System.out.println("服務(wù)器說:"+str); //打印接收數(shù)據(jù)
}
}
catch(Exception e){}
}
}
用戶2:
[java] view plain copy
import java.util.*;
import java.io.*;
import java.net.*;
public class Server{
public static void main(String[]args)throws Exception{
ServerSocket server = new ServerSocket(8819);
Socket s = server.accept();
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
Thread t = new Thread(new Receive1(s));
t.start();
//以下代碼用于發(fā)送數(shù)據(jù)
Scanner in = new Scanner(System.in);//鍵盤輸入
while(in.hasNextLine()){ //一直不斷
out.println(in.nextLine()); //發(fā)送鍵盤輸入數(shù)據(jù)
}
}
}
class Receive1 implements Runnable //這個類用于接收數(shù)據(jù)
{
private Socket s;
public Receive1(Socket s)
{
this.s = s;
}
public void run()
{
try{
Scanner in = new Scanner(s.getInputStream()); //in:接收數(shù)據(jù)
String str = null;
while(true)
{
str = in.nextLine();
System.out.println("客戶端說:"+str); //打印接收數(shù)據(jù)
}
}
catch(Exception e){}
}
}
以上的程序?qū)儆贑/S,需要同時維護(hù)客戶端和服務(wù)器的代碼。
B/S:瀏覽器和服務(wù)器,只需要維護(hù)一方代碼即可。
【java網(wǎng)絡(luò)編程基本知識】相關(guān)文章:
Java基本編程技巧11-16
Java編程開發(fā)簡介08-17
關(guān)于JAVA的XML編程10-08
Java編程常見問題匯總08-22
Java中的動態(tài)代碼編程08-15
Java代碼的基本知識08-14
Java編程中如何實(shí)現(xiàn)中文排序09-27
JAVA編程面試題及答案09-16