|
網(wǎng)絡(luò)編程就是 圖片說(shuō)明 圖片說(shuō)明 一座塔有七層,我們需要闖關(guān). 第一層物理層->第二層數(shù)據(jù)鏈路層->第三層網(wǎng)絡(luò)層->第四層傳輸層->第五層會(huì)話層->第六層表示層->第七層應(yīng)用層. 物理層是主要定義物理設(shè)備標(biāo)準(zhǔn),數(shù)據(jù)鏈路層是主要講從物理層接收的數(shù)據(jù)進(jìn)行 網(wǎng)絡(luò)層是將從下層接收到的數(shù)據(jù)進(jìn)行 會(huì)話層是將通過(guò)傳輸層建立數(shù)據(jù)傳輸?shù)耐?表示層是進(jìn)行對(duì)接收的數(shù)據(jù)進(jìn)行解釋,加密與解密. 應(yīng)用層主要是一些終端的應(yīng)用.
圖片說(shuō)明 圖片說(shuō)明
端口號(hào)是用來(lái)標(biāo)識(shí)進(jìn)程的邏輯地址,不同進(jìn)行的標(biāo)識(shí),有效的端口為 傳輸協(xié)議即是通訊的規(guī)則,常見(jiàn)的協(xié)議為
類 |
| 類型 | 方法 | 說(shuō)明 |
|---|---|---|
boolean | equals(Object obj) | 將此對(duì)象與指定對(duì)象進(jìn)行比較 |
byte[] | getAddress() | 返回此InetAddress對(duì)象的原始ip地址. |
static InetAddress[] | getAllByName(String host) | 給定主機(jī)的名稱,根據(jù)系統(tǒng)上配置的名稱服務(wù)返回其ip地址數(shù)組. |
static InetAddress | getByAddress(byte[] addr) | 給出原始IP地址的InetAddress對(duì)象 |
static InetAddress | getByAddress(String host, byte[] addr) | 根據(jù)提供的主機(jī)名和ip地址創(chuàng)建InetAddress |
static InetAddress | getByName(String host) | 確定主機(jī)名稱的ip地址 |
String | getCanonicalHostName() | 獲取此ip地址的完全限定域名 |
String | getHostAddress() | 返回文本顯示中的ip地址字符串 |
String | getHostName() | 獲取此ip地址的主機(jī)名 |
1,網(wǎng)絡(luò)模型:7層--->4層
端口
用于標(biāo)識(shí)進(jìn)程的邏輯地址,不同進(jìn)程的標(biāo)識(shí)
有效端口:0到65535,而0到1024系統(tǒng)使用或保留端口
傳輸協(xié)議
TCP``UDPTCP和UDP的區(qū)別:
TCP: 面向連接,通過(guò)三次握手完成,速度慢,可靠。
UDP: 面向無(wú)連接,速度快,不可靠。
UDP是將數(shù)據(jù)及其源和目的封裝成數(shù)據(jù)包中,不需要建立連接,每個(gè)數(shù)據(jù)報(bào)的大小在限制在64k內(nèi),因無(wú)連接,是不可靠的協(xié)議,不需要連接,但是速度快.
TCP是需要進(jìn)行連接的,形成傳輸數(shù)據(jù)的通道,在連接中進(jìn)行大數(shù)據(jù)量傳輸,通過(guò)三次握手完成連接,是可靠的協(xié)議,效率低即是速度慢一點(diǎn).
網(wǎng)絡(luò)編程-Socket
網(wǎng)絡(luò)通訊的要素:
ip
端口
傳輸協(xié)議
ip是用于標(biāo)識(shí)網(wǎng)絡(luò)中主機(jī)的數(shù)字標(biāo)識(shí),而端口是用于標(biāo)識(shí)應(yīng)用程序的數(shù)字,還有傳輸協(xié)議是用于進(jìn)行數(shù)據(jù)傳輸?shù)囊?guī)則.
實(shí)現(xiàn)UDP的通信,TCP傳輸:客戶端,服務(wù)端.
Socket是網(wǎng)絡(luò)服務(wù)提供的一種機(jī)制,是通信兩端必備的,都要有Socket,網(wǎng)絡(luò)通信其實(shí)就是Socket間的通信,數(shù)據(jù)在兩個(gè)Socket間通過(guò)io傳輸.
UDPUDP發(fā)送端Demo
public class UDPSend{
public static void main(String[] args){
System.out.println('udp發(fā)送端');
}
}DatagramSocket
public class DatagramSocket extends Object此類表示用來(lái)發(fā)送和接收數(shù)據(jù)報(bào)包的套接字.
數(shù)據(jù)報(bào)套接字是包投遞服務(wù)的發(fā)送或接收點(diǎn).每個(gè)在數(shù)據(jù)報(bào)套接字上發(fā)送或接收的包都是單獨(dú)編址和路由的.從一臺(tái)機(jī)器發(fā)送到另一臺(tái)機(jī)器的多個(gè)包可能選擇不同的路由,也可能按不同的順序到達(dá).
在DatagramSocket上總是啟動(dòng)UDP廣播發(fā)送.為了接收廣播包,將DatagramSocket綁定到通配符地址.
圖片說(shuō)明
void receive(DatagramPacket p)
從此套接字接收數(shù)據(jù)報(bào)包
send(DatagramPacket p)
從此套接字發(fā)送數(shù)據(jù)報(bào)包public class UDPSend{
public static void main(String[] args) throws IOException{
System.out.println('udp發(fā)送端');
DatagramSocket ds = new DatagramSocket();
String text = 'hello';
byte[] buf = text.getBytes();
// 將數(shù)據(jù)轉(zhuǎn)成字節(jié)數(shù)組
DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName('123.23232.323.2'),10000);
ds.send(dp);
ds.close();
}
}
// 建立upd的socket,具備發(fā)送或接收功能
// 將數(shù)據(jù)封裝到數(shù)據(jù)包中,數(shù)據(jù)包對(duì)象是DatagramPacket.
// 使用socket對(duì)象的send方法將數(shù)據(jù)包發(fā)出去.
// 關(guān)閉資源udp接收端
public class updDemo {
public static void main(String[] args) throws IOException {
System.out.println('udp 接收端');
// 先有udpsocket服務(wù)
// 接收數(shù)據(jù)
DatagramSocket ds = new DatagramSocket();
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort():
String text = new String(dp.getData(),0,dp.getLength());
// 關(guān)閉資源。
ds.close();
}
}receive
public void receive(DatagramPacket p) throws IOException
此套接字接收數(shù)據(jù)報(bào)包實(shí)現(xiàn)UDP的通信,udp傳輸涉及的兩個(gè)對(duì)象,即可以發(fā)送,又可以接收.TCP傳輸:客戶端,服務(wù)端.
UDP鍵盤輸入
public class UDPSend {
public static void main(String[] args) throws IOException {
System.out.println('udp 發(fā)送端 run');
// 1,建立udp的socket它具備者發(fā)送或者接收功能。
DatagramSocket ds = new DatagramSocket(9999);
// 2,將數(shù)據(jù)封裝到數(shù)據(jù)包中。數(shù)據(jù)包對(duì)象是DatagramPacket。數(shù)據(jù)來(lái)自于鍵盤錄入。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line=bufr.readLine())!=null){
if('over'.equals(line)){
break;
}
byte[] buf = line.getBytes();//將數(shù)據(jù)轉(zhuǎn)成字節(jié)數(shù)組。
// 將字節(jié)數(shù)組封裝到數(shù)據(jù)包中。
DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName('192.168.1.223'), 10001);
// 3,使用socket對(duì)象的send方法將數(shù)據(jù)包發(fā)送出去。
ds.send(dp);
}
// 4,關(guān)閉資源。
ds.close();
}
}public class UDPRece {
public static void main(String[] args) throws IOException {
System.out.println('udp2 接收端 run');
DatagramSocket ds = new DatagramSocket(10001);
while (true) {
// 2,接收數(shù)據(jù)。
// 3,先定義數(shù)據(jù)包。
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
ds.receive(dp);
// 4,通過(guò)數(shù)據(jù)包對(duì)象獲取數(shù)據(jù)包的內(nèi)容,發(fā)送端的ip。發(fā)送端的端口,發(fā)送過(guò)來(lái)的數(shù)據(jù)。
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String text = new String(dp.getData(), 0, dp.getLength());
System.out.println(ip + ':' + port + ':' + text);
}
// 5,關(guān)閉資源。
// ds.close();
}
}案例:
public class UDPChatTest {
public static void main(String[] args) throws IOException {
//發(fā)送端的socket 接收端的socket
DatagramSocket sendSocket = new DatagramSocket();
DatagramSocket receSocket = new DatagramSocket(10002);
//創(chuàng)建任務(wù)對(duì)象。
Send send = new Send(sendSocket);
Rece rece = new Rece(receSocket);
//創(chuàng)建線程并開(kāi)啟。
Thread t1 = new Thread(send);
Thread t2 = new Thread(rece);
t1.start();
t2.start();
}
}
// 發(fā)送任務(wù)
class Send implements Runnable {
private DatagramSocket ds;
public Send(DatagramSocket ds) {
super();
this.ds = ds;
}
@Override
public void run() {
try {
BufferedReader bufr = new BufferedReader(new InputStreamReader(
System.in));
String line = null;
while ((line = bufr.readLine()) != null) {
byte[] buf = line.getBytes();// 將數(shù)據(jù)轉(zhuǎn)成字節(jié)數(shù)組。
DatagramPacket dp = new DatagramPacket(buf, buf.length,
InetAddress.getByName('1928.1.223'), 10002);
ds.send(dp);
if ('886'.equals(line)) {
break;
}
}
// 4,關(guān)閉資源。
ds.close();
} catch (IOException e) {
}
}
}
// 接收任務(wù)。
class Rece implements Runnable {
private DatagramSocket ds;
public Rece(DatagramSocket ds) {
super();
this.ds = ds;
}
@Override
public void run() {
while (true) {
try {
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
ds.receive(dp);// 阻塞
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String text = new String(dp.getData(), 0, dp.getLength());
System.out.println(ip + ':' + port + ':' + text);
if(text.equals('886')){
System.out.println(ip+'....離開(kāi)聊天室');
}
} catch (IOException e) {
}
}
}
}tcp案例:
public class TCPClient {
public static void main(String[] args) throws IOException {
System.out.println('客戶端運(yùn)行.......');
// 1,建立tcp的客戶端socket。明確服務(wù)端的地址和端口。
Socket s = new Socket('192.1.223',10003);
// 2,如果通道建立成功就會(huì)出現(xiàn)socket io流。
// 客戶端需要做的就獲取socket流的中輸出流將數(shù)據(jù)發(fā)送目的地服務(wù)端。
OutputStream out = s.getOutputStream();
// 3,通過(guò)socket輸出流將數(shù)據(jù)發(fā)送。
out.write('hello tcp 來(lái)了!'.getBytes());
// 4,關(guān)閉資源。
s.close();
}
}public class TCPServer {
public static void main(String[] args) throws IOException {
System.out.println('服務(wù)端開(kāi)啟.....');
ServerSocket ss = new ServerSocket(10003);
while (true) {
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf, 0, len);
System.out.println(text);
s.close();
}
}
}案例:
public class TCPClient2 {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println('客戶端2 啟動(dòng).......');
Socket s = new Socket('192.1623', 10004);
OutputStream out = s.getOutputStream();
out.write('服務(wù)端,我來(lái)了'.getBytes());
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf,0,len);
System.out.println(text);
// 關(guān)閉資源。
s.close();
}
}public class TCPSever2 {
public static void main(String[] args) throws IOException {
System.out.println('服務(wù)端2啟動(dòng).....');
ServerSocket ss = new ServerSocket(10004);
while (true) {
// 獲取客戶端對(duì)象。
Socket s = ss.accept();
// 讀取客戶端的發(fā)送過(guò)來(lái)的數(shù)據(jù)
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf, 0, len);
System.out.println(text);
// 給客戶端回饋數(shù)據(jù)。
OutputStream out = s.getOutputStream();
out.write('客戶端,我已到收到,哦耶!'.getBytes());
// 關(guān)閉客戶端
s.close();
}
// 關(guān)閉服務(wù)端。如果不斷的獲取客戶端,不用關(guān)閉服務(wù)端。
// ss.close();
}
}|
|
來(lái)自: 蘭亭文藝 > 《編程是一門藝術(shù)》