摘要:應(yīng)用層主要負責(zé)應(yīng)用程序的協(xié)議,例如協(xié)議協(xié)議等。在計算機中,不同的應(yīng)用程序是通過端口號區(qū)分的。區(qū)別在于,中只有發(fā)送端和接收端,不區(qū)分客戶端與服務(wù)器端,計算機之間可以任意地發(fā)送數(shù)據(jù)。
01網(wǎng)絡(luò)模型
*A:網(wǎng)絡(luò)模型
TCP/IP協(xié)議中的四層分別是應(yīng)用層、傳輸層、網(wǎng)絡(luò)層和鏈路層,每層分別負責(zé)不同的通信功能,接下來針對這四層進行詳細地講解。 鏈路層:鏈路層是用于定義物理傳輸通道,通常是對某些網(wǎng)絡(luò)連接設(shè)備的驅(qū)動協(xié)議,例如針對光纖、網(wǎng)線提供的驅(qū)動。 網(wǎng)絡(luò)層:網(wǎng)絡(luò)層是整個TCP/IP協(xié)議的核心,它主要用于將傳輸?shù)臄?shù)據(jù)進行分組,將分組數(shù)據(jù)發(fā)送到目標(biāo)計算機或者網(wǎng)絡(luò)。 傳輸層:主要使網(wǎng)絡(luò)程序進行通信,在進行網(wǎng)絡(luò)通信時,可以采用TCP協(xié)議,也可以采用UDP協(xié)議。 應(yīng)用層:主要負責(zé)應(yīng)用程序的協(xié)議,例如HTTP協(xié)議、FTP協(xié)議等。02IP地址
*A:IP地址
在TCP/IP協(xié)議中,這個標(biāo)識號就是IP地址,它可以唯一標(biāo)識一臺計算機, 目前,IP地址廣泛使用的版本是IPv4,它是由4個字節(jié)大小的二進制數(shù)來表示,如:00001010000000000000000000000001。 由于二進制形式表示的IP地址非常不便記憶和處理,因此通常會將IP地址寫成十進制的形式, 每個字節(jié)用一個十進制數(shù)字(0-255)表示,數(shù)字間用符號“.”分開,如 “192.168.1.100” 127.0.0.1 為本地主機地址(本地回環(huán)地址)03端口號
*A:端口號
通過IP地址可以連接到指定計算機,但如果想訪問目標(biāo)計算機中的某個應(yīng)用程序,還需要指定端口號。 在計算機中,不同的應(yīng)用程序是通過端口號區(qū)分的。 端口號是用兩個字節(jié)(16位的二進制數(shù))表示的,它的取值范圍是0~65535, 其中,0~1023之間的端口號用于一些知名的網(wǎng)絡(luò)服務(wù)和應(yīng)用,用戶的普通應(yīng)用程序需要使用1024以上的端口號,從而避免端口號被另外一個應(yīng)用或服務(wù)所占用04InetAddress類
*A:InetAddress類
/* * 表示互聯(lián)網(wǎng)中的IP地址 * java.net.InetAddress * 靜態(tài)方法 * static InetAddress getLocalHost() LocalHost本地主機 * 返回本地主機,返回值InetAddress對象 * * static InetAddress getByName(String hostName)傳遞主機名,獲取IP地址對象 * * 非靜態(tài)方法 * String getHoustAddress()獲取主機IP地址 * String getHoustName()獲取主機名 * */ public class InetAddressDemo { public static void main(String[] args)throws UnknownHostException { function_1(); } /* * static InetAddress getByName(String hostName)傳遞主機名,獲取IP地址對象 */ public static void function_1()throws UnknownHostException { InetAddress inet = InetAddress.getByName("www.baidu.com"); System.out.println(inet); } /* * static InetAddress getLocalHost() LocalHost本地主機 */ public static void function() throws UnknownHostException{ InetAddress inet = InetAddress.getLocalHost(); //輸出結(jié)果就是主機名,和 IP地址 System.out.println(inet.toString()); String ip = inet.getHostAddress(); String name = inet.getHostName(); System.out.println(ip+" "+name); /*String host = inet.toString(); String[] str = host.split("/"); for(String s : str){ System.out.println(s); }*/ } }05UDP協(xié)議
A:UDP協(xié)議
a:UDP協(xié)議概述: UDP是無連接通信協(xié)議,即在數(shù)據(jù)傳輸時,數(shù)據(jù)的發(fā)送端和接收端不建立邏輯連接。 簡單來說,當(dāng)一臺計算機向另外一臺計算機發(fā)送數(shù)據(jù)時,發(fā)送端不會確認接收端是否存在,就會發(fā)出數(shù)據(jù),同樣接收端在收到數(shù)據(jù)時,也不會向發(fā)送端反饋是否收到數(shù)據(jù)。 b:UDP協(xié)議特點: 由于使用UDP協(xié)議消耗資源小,通信效率高,所以通常都會用于音頻、視頻和普通數(shù)據(jù)的傳輸例如視頻會議都使用UDP協(xié)議, 因為這種情況即使偶爾丟失一兩個數(shù)據(jù)包,也不會對接收結(jié)果產(chǎn)生太大影響。06TCP協(xié)議
*A:TCP協(xié)議
TCP協(xié)議是面向連接的通信協(xié)議,即在傳輸數(shù)據(jù)前先在發(fā)送端和接收端建立邏輯連接,然后再傳輸數(shù)據(jù),它提供了兩臺計算機之間可靠無差錯的數(shù)據(jù)傳輸。 在TCP連接中必須要明確客戶端與服務(wù)器端, 由客戶端向服務(wù)端發(fā)出連接請求,每次連接的創(chuàng)建都需要經(jīng)過“三次握手”。 第一次握手,客戶端向服務(wù)器端發(fā)出連接請求,等待服務(wù)器確認 第二次握手,服務(wù)器端向客戶端回送一個響應(yīng),通知客戶端收到了連接請求 第三次握手,客戶端再次向服務(wù)器端發(fā)送確認信息,確認連接
========================================第二節(jié)課=========================================
07數(shù)據(jù)包和發(fā)送對象介紹*A:數(shù)據(jù)包和發(fā)送對象介紹:
DatagramPacket數(shù)據(jù)包的作用就如同是“集裝箱”, 可以將發(fā)送端或者接收端的數(shù)據(jù)封裝起來。然而運輸貨物只有“集裝箱”是不夠的,還需要有碼頭。 在程序中需要實現(xiàn)通信只有DatagramPacket數(shù)據(jù)包也同樣不行,為此JDK中提供的一個DatagramSocket類。 DatagramSocket類的作用就類似于碼頭,使用這個類的實例對象就可以發(fā)送和接收DatagramPacket數(shù)據(jù)包 DatagramPacket:封裝數(shù)據(jù) DatagramSocket:發(fā)送DatagramPacket08UDP發(fā)送端
*A:UDP發(fā)送端
/* * 實現(xiàn)UDP協(xié)議的發(fā)送端: * 實現(xiàn)封裝數(shù)據(jù)的類 java.net.DatagramPacket 將你的數(shù)據(jù)包裝 * 實現(xiàn)數(shù)據(jù)傳輸?shù)念?java.net.DatagramSocket 將數(shù)據(jù)包發(fā)出去 * * 實現(xiàn)步驟: * 1. 創(chuàng)建DatagramPacket對象,封裝數(shù)據(jù), 接收的地址和端口 * 2. 創(chuàng)建DatagramSocket * 3. 調(diào)用DatagramSocket類方法send,發(fā)送數(shù)據(jù)包 * 4. 關(guān)閉資源 * * DatagramPacket構(gòu)造方法: * DatagramPacket(byte[] buf, int length, InetAddress address, int port) * * DatagramSocket構(gòu)造方法: * DatagramSocket()空參數(shù) * 方法: send(DatagramPacket d) * */ public class UDPSend { public static void main(String[] args) throws IOException{ //創(chuàng)建數(shù)據(jù)包對象,封裝要發(fā)送的數(shù)據(jù),接收端IP,端口 byte[] date = "你好UDP".getBytes(); //創(chuàng)建InetAddress對象,封裝自己的IP地址 InetAddress inet = InetAddress.getByName("127.0.0.1"); DatagramPacket dp = new DatagramPacket(date, date.length, inet,6000); //創(chuàng)建DatagramSocket對象,數(shù)據(jù)包的發(fā)送和接收對象 DatagramSocket ds = new DatagramSocket(); //調(diào)用ds對象的方法send,發(fā)送數(shù)據(jù)包 ds.send(dp); //關(guān)閉資源 ds.close(); } }09UDP接收端
*A:UDP接收端
/* * 實現(xiàn)UDP接收端 * 實現(xiàn)封裝數(shù)據(jù)包 java.net.DatagramPacket 將數(shù)據(jù)接收 * 實現(xiàn)輸出傳輸 java.net.DatagramSocket 接收數(shù)據(jù)包 * * 實現(xiàn)步驟: * 1. 創(chuàng)建DatagramSocket對象,綁定端口號 * 要和發(fā)送端端口號一致 * 2. 創(chuàng)建字節(jié)數(shù)組,接收發(fā)來的數(shù)據(jù) * 3. 創(chuàng)建數(shù)據(jù)包對象DatagramPacket * 4. 調(diào)用DatagramSocket對象方法 * receive(DatagramPacket dp)接收數(shù)據(jù),數(shù)據(jù)放在數(shù)據(jù)包中 * 5. 拆包 * 發(fā)送的IP地址 * 數(shù)據(jù)包對象DatagramPacket方法getAddress()獲取的是發(fā)送端的IP地址對象 * 返回值是InetAddress對象 * 接收到的字節(jié)個數(shù) * 數(shù)據(jù)包對象DatagramPacket方法 getLength() * 發(fā)送方的端口號 * 數(shù)據(jù)包對象DatagramPacket方法 getPort()發(fā)送端口 * 6. 關(guān)閉資源 */ public class UDPReceive { public static void main(String[] args)throws IOException { //創(chuàng)建數(shù)據(jù)包傳輸對象DatagramSocket 綁定端口號 DatagramSocket ds = new DatagramSocket(6000); //創(chuàng)建字節(jié)數(shù)組 byte[] data = new byte[1024]; //創(chuàng)建數(shù)據(jù)包對象,傳遞字節(jié)數(shù)組 DatagramPacket dp = new DatagramPacket(data, data.length); //調(diào)用ds對象的方法receive傳遞數(shù)據(jù)包 ds.receive(dp); } }10UDP接收端的拆包
*A:UDP接收端的拆包
/* * 實現(xiàn)UDP接收端 * 實現(xiàn)封裝數(shù)據(jù)包 java.net.DatagramPacket 將數(shù)據(jù)接收 * 實現(xiàn)輸出傳輸 java.net.DatagramSocket 接收數(shù)據(jù)包 * * 實現(xiàn)步驟: * 1. 創(chuàng)建DatagramSocket對象,綁定端口號 * 要和發(fā)送端端口號一致 * 2. 創(chuàng)建字節(jié)數(shù)組,接收發(fā)來的數(shù)據(jù) * 3. 創(chuàng)建數(shù)據(jù)包對象DatagramPacket * 4. 調(diào)用DatagramSocket對象方法 * receive(DatagramPacket dp)接收數(shù)據(jù),數(shù)據(jù)放在數(shù)據(jù)包中 * 5. 拆包 * 發(fā)送的IP地址 * 數(shù)據(jù)包對象DatagramPacket方法getAddress()獲取的是發(fā)送端的IP地址對象 * 返回值是InetAddress對象 * 接收到的字節(jié)個數(shù) * 數(shù)據(jù)包對象DatagramPacket方法 getLength() * 發(fā)送方的端口號 * 數(shù)據(jù)包對象DatagramPacket方法 getPort()發(fā)送端口 * 6. 關(guān)閉資源 */ public class UDPReceive { public static void main(String[] args)throws IOException { //創(chuàng)建數(shù)據(jù)包傳輸對象DatagramSocket 綁定端口號 DatagramSocket ds = new DatagramSocket(6000); //創(chuàng)建字節(jié)數(shù)組 byte[] data = new byte[1024]; //創(chuàng)建數(shù)據(jù)包對象,傳遞字節(jié)數(shù)組 DatagramPacket dp = new DatagramPacket(data, data.length); //調(diào)用ds對象的方法receive傳遞數(shù)據(jù)包 ds.receive(dp); //獲取發(fā)送端的IP地址對象 String ip=dp.getAddress().getHostAddress(); //獲取發(fā)送的端口號 int port = dp.getPort(); //獲取接收到的字節(jié)個數(shù) int length = dp.getLength(); System.out.println(new String(data,0,length)+"..."+ip+":"+port); ds.close(); } }11鍵盤輸入的聊天
*A:鍵盤輸入的聊天
*a:發(fā)送端: /* * 實現(xiàn)UDP發(fā)送,鍵盤輸入的形式 * 輸入完畢,發(fā)送給接收端 */ public class UDPSend { public static void main(String[] args) throws IOException{ Scanner sc = new Scanner(System.in); DatagramSocket ds = new DatagramSocket(); InetAddress inet = InetAddress.getByName("127.0.0.1"); while(true){ String message = sc.nextLine(); /*if("886".equals(message)){ break; }*/ byte[] date = message.getBytes(); DatagramPacket dp = new DatagramPacket(date, date.length, inet,6000); ds.send(dp); } // ds.close(); } } /* * 實現(xiàn)UDP接收端 * 永不停歇的接收端 */ public class UDPReceive { public static void main(String[] args)throws IOException { //創(chuàng)建數(shù)據(jù)包傳輸對象DatagramSocket 綁定端口號 DatagramSocket ds = new DatagramSocket(6000); //創(chuàng)建字節(jié)數(shù)組 byte[] data = new byte[1024]; //創(chuàng)建數(shù)據(jù)包對象,傳遞字節(jié)數(shù)組 while(true){ DatagramPacket dp = new DatagramPacket(data, data.length); //調(diào)用ds對象的方法receive傳遞數(shù)據(jù)包 ds.receive(dp); //獲取發(fā)送端的IP地址對象 String ip=dp.getAddress().getHostAddress(); //獲取發(fā)送的端口號 int port = dp.getPort(); //獲取接收到的字節(jié)個數(shù) int length = dp.getLength(); System.out.println(new String(data,0,length)+"..."+ip+":"+port); } //ds.close(); } }
=======================第三節(jié)課======================================
12TCP的客戶端和服務(wù)器*A:TCP的客戶端和服務(wù)器
TCP通信同UDP通信一樣,都能實現(xiàn)兩臺計算機之間的通信,通信的兩端都需要創(chuàng)建socket對象。 區(qū)別在于,UDP中只有發(fā)送端和接收端,不區(qū)分客戶端與服務(wù)器端,計算機之間可以任意地發(fā)送數(shù)據(jù)。 而TCP通信是嚴格區(qū)分客戶端與服務(wù)器端的,在通信時,必須先由客戶端去連接服務(wù)器端才能實現(xiàn)通信, 服務(wù)器端不可以主動連接客戶端,并且服務(wù)器端程序需要事先啟動,等待客戶端的連接。 在JDK中提供了兩個類用于實現(xiàn)TCP程序,一個是ServerSocket類,用于表示服務(wù)器端,一個是Socket類,用于表示客戶端。 通信時,首先創(chuàng)建代表服務(wù)器端的ServerSocket對象,該對象相當(dāng)于開啟一個服務(wù),并等待客戶端的連接,然后創(chuàng)建代表客戶端的Socket對象向服務(wù)器端發(fā)出連接請求,服務(wù)器端響應(yīng)請求,兩者建立連接開始通信。13TCP的客戶端程序
*A:TCP的客戶端程序
/*
* 實現(xiàn)TCP客戶端,連接到服務(wù)器 * 和服務(wù)器實現(xiàn)數(shù)據(jù)交換 * 實現(xiàn)TCP客戶端程序的類 java.net.Socket * * 構(gòu)造方法: * Socket(String host, int port) 傳遞服務(wù)器IP和端口號 * 注意:構(gòu)造方法只要運行,就會和服務(wù)器進行連接,連接失敗,拋出異常 * * OutputStream getOutputStream() 返回套接字的輸出流 * 作用: 將數(shù)據(jù)輸出,輸出到服務(wù)器 * * InputStream getInputStream() 返回套接字的輸入流 * 作用: 從服務(wù)器端讀取數(shù)據(jù) * * 客戶端服務(wù)器數(shù)據(jù)交換,必須使用套接字對象Socket中的獲取的IO流,自己new流,不行 */
public class TCPClient {
public static void main(String[] args)throws IOException { //創(chuàng)建Socket對象,連接服務(wù)器 Socket socket = new Socket("127.0.0.1", 8888); //通過客戶端的套接字對象Socket方法,獲取字節(jié)輸出流,將數(shù)據(jù)寫向服務(wù)器 OutputStream out = socket.getOutputStream(); out.write("服務(wù)器OK".getBytes()); socket.close(); }
}
14TCP的服務(wù)器程序accept方法A:TCP的服務(wù)器程序accept方法
/* * 實現(xiàn)TCP服務(wù)器程序 * 表示服務(wù)器程序的類 java.net.ServerSocket * 構(gòu)造方法: * ServerSocket(int port) 傳遞端口號 * * 很重要的事情: 必須要獲得客戶端的套接字對象Socket * Socket accept() */ public class TCPServer { public static void main(String[] args) throws IOException{ ServerSocket server = new ServerSocket(8888); //調(diào)用服務(wù)器套接字對象中的方法accept() 獲取客戶端套接字對象 Socket socket = server.accept(); //通過客戶端套接字對象,socket獲取字節(jié)輸入流,讀取的是客戶端發(fā)送來的數(shù)據(jù) InputStream in = socket.getInputStream(); byte[] data = new byte[1024]; int len = in.read(data); System.out.println(new String(data,0,len)); socket.close(); server.close(); } }15TCP的服務(wù)器程序讀取客戶端數(shù)據(jù)
A:TCP的服務(wù)器程序讀取客戶端數(shù)據(jù)
/* * 實現(xiàn)TCP客戶端,連接到服務(wù)器 * 和服務(wù)器實現(xiàn)數(shù)據(jù)交換 * 實現(xiàn)TCP客戶端程序的類 java.net.Socket * * 構(gòu)造方法: * Socket(String host, int port) 傳遞服務(wù)器IP和端口號 * 注意:構(gòu)造方法只要運行,就會和服務(wù)器進行連接,連接失敗,拋出異常 * * OutputStream getOutputStream() 返回套接字的輸出流 * 作用: 將數(shù)據(jù)輸出,輸出到服務(wù)器 * * InputStream getInputStream() 返回套接字的輸入流 * 作用: 從服務(wù)器端讀取數(shù)據(jù) * * 客戶端服務(wù)器數(shù)據(jù)交換,必須使用套接字對象Socket中的獲取的IO流,自己new流,不行 */ public class TCPClient { public static void main(String[] args)throws IOException { //創(chuàng)建Socket對象,連接服務(wù)器 Socket socket = new Socket("127.0.0.1", 8888); //通過客戶端的套接字對象Socket方法,獲取字節(jié)輸出流,將數(shù)據(jù)寫向服務(wù)器 OutputStream out = socket.getOutputStream(); out.write("服務(wù)器OK".getBytes()); socket.close(); } } /* * 實現(xiàn)TCP服務(wù)器程序 * 表示服務(wù)器程序的類 java.net.ServerSocket * 構(gòu)造方法: * ServerSocket(int port) 傳遞端口號 * * 很重要的事情: 必須要獲得客戶端的套接字對象Socket * Socket accept() */ public class TCPServer { public static void main(String[] args) throws IOException{ ServerSocket server = new ServerSocket(8888); //調(diào)用服務(wù)器套接字對象中的方法accept() 獲取客戶端套接字對象 Socket socket = server.accept(); //通過客戶端套接字對象,socket獲取字節(jié)輸入流,讀取的是客戶端發(fā)送來的數(shù)據(jù) InputStream in = socket.getInputStream(); byte[] data = new byte[1024]; int len = in.read(data); System.out.println(new String(data,0,len)); } }16TCP的服務(wù)器和客戶端的數(shù)據(jù)交換
A:TCP的服務(wù)器和客戶端的數(shù)據(jù)交換
/* * 實現(xiàn)TCP客戶端,連接到服務(wù)器 * 和服務(wù)器實現(xiàn)數(shù)據(jù)交換 * 實現(xiàn)TCP客戶端程序的類 java.net.Socket * * 構(gòu)造方法: * Socket(String host, int port) 傳遞服務(wù)器IP和端口號 * 注意:構(gòu)造方法只要運行,就會和服務(wù)器進行連接,連接失敗,拋出異常 * * OutputStream getOutputStream() 返回套接字的輸出流 * 作用: 將數(shù)據(jù)輸出,輸出到服務(wù)器 * * InputStream getInputStream() 返回套接字的輸入流 * 作用: 從服務(wù)器端讀取數(shù)據(jù) * * 客戶端服務(wù)器數(shù)據(jù)交換,必須使用套接字對象Socket中的獲取的IO流,自己new流,不行 */ public class TCPClient { public static void main(String[] args)throws IOException { //創(chuàng)建Socket對象,連接服務(wù)器 Socket socket = new Socket("127.0.0.1", 8888); //通過客戶端的套接字對象Socket方法,獲取字節(jié)輸出流,將數(shù)據(jù)寫向服務(wù)器 OutputStream out = socket.getOutputStream(); out.write("服務(wù)器OK".getBytes()); //讀取服務(wù)器發(fā)回的數(shù)據(jù),使用socket套接字對象中的字節(jié)輸入流 InputStream in = socket.getInputStream(); byte[] data = new byte[1024]; int len = in.read(data); System.out.println(new String(data,0,len)); socket.close(); } } /* * 實現(xiàn)TCP服務(wù)器程序 * 表示服務(wù)器程序的類 java.net.ServerSocket * 構(gòu)造方法: * ServerSocket(int port) 傳遞端口號 * * 很重要的事情: 必須要獲得客戶端的套接字對象Socket * Socket accept() */ public class TCPServer { public static void main(String[] args) throws IOException{ ServerSocket server = new ServerSocket(8888); //調(diào)用服務(wù)器套接字對象中的方法accept() 獲取客戶端套接字對象 Socket socket = server.accept(); //通過客戶端套接字對象,socket獲取字節(jié)輸入流,讀取的是客戶端發(fā)送來的數(shù)據(jù) InputStream in = socket.getInputStream(); byte[] data = new byte[1024]; int len = in.read(data); System.out.println(new String(data,0,len)); //服務(wù)器向客戶端回數(shù)據(jù),字節(jié)輸出流,通過客戶端套接字對象獲取字節(jié)輸出流 OutputStream out = socket.getOutputStream(); out.write("收到,謝謝".getBytes()); socket.close(); server.close(); } }17TCP的中的流對象
*A:TCP的中的流對象 參見圖解TCP中的流對象.jpg
======================================第四節(jié)課=================================================
18TCP圖片上傳案例分析*A:圖片上傳案例分析 參見圖解TCP上傳圖片案例.jpg19TCP上傳客戶端
*A TCP上傳客戶端
/*
* 實現(xiàn)TCP圖片上傳客戶端 * 實現(xiàn)步驟: * 1. Socket套接字連接服務(wù)器 * 2. 通過Socket獲取字節(jié)輸出流,寫圖片 * 3. 使用自己的流對象,讀取圖片數(shù)據(jù)源 * FileInputStream * 4. 讀取圖片,使用字節(jié)輸出流,將圖片寫到服務(wù)器 * 采用字節(jié)數(shù)組進行緩沖 * 5. 通過Socket套接字獲取字節(jié)輸入流 * 讀取服務(wù)器發(fā)回來的上傳成功 * 6. 關(guān)閉資源 */
public class TCPClient {
public static void main(String[] args) throws IOException{ Socket socket = new Socket("127.0.0.1", 8000); //獲取字節(jié)輸出流,圖片寫到服務(wù)器 OutputStream out = socket.getOutputStream(); //創(chuàng)建字節(jié)輸入流,讀取本機上的數(shù)據(jù)源圖片 FileInputStream fis = new FileInputStream("c: .jpg"); //開始讀寫字節(jié)數(shù)組 int len = 0 ; byte[] bytes = new byte[1024]; while((len = fis.read(bytes))!=-1){ out.write(bytes, 0, len); } //給服務(wù)器寫終止序列 //socket.shutdownOutput(); //獲取字節(jié)輸入流,讀取服務(wù)器的上傳成功 InputStream in = socket.getInputStream(); len = in.read(bytes); System.out.println(new String(bytes,0,len)); fis.close(); socket.close(); }
}
20TCP上傳服務(wù)器A:TCP上傳服務(wù)器
/*
* TCP圖片上傳服務(wù)器 * 1. ServerSocket套接字對象,監(jiān)聽端口8000 * 2. 方法accept()獲取客戶端的連接對象 * 3. 客戶端連接對象獲取字節(jié)輸入流,讀取客戶端發(fā)送圖片 * 4. 創(chuàng)建File對象,綁定上傳文件夾 * 判斷文件夾存在, 不存,在創(chuàng)建文件夾 * 5. 創(chuàng)建字節(jié)輸出流,數(shù)據(jù)目的File對象所在文件夾 * 6. 字節(jié)流讀取圖片,字節(jié)流將圖片寫入到目的文件夾中 * 7. 將上傳成功會寫客戶端 * 8. 關(guān)閉資源 * */
public class TCPServer {
public static void main(String[] args) throws IOException{ ServerSocket server = new ServerSocket(8000); Socket socket = server.accept(); //通過客戶端連接對象,獲取字節(jié)輸入流,讀取客戶端圖片 InputStream in = socket.getInputStream(); //將目的文件夾封裝到File對象 File upload = new File("d:upload"); if(!upload.exists()) upload.mkdirs(); //創(chuàng)建字節(jié)輸出流,將圖片寫入到目的文件夾中 FileOutputStream fos = new FileOutputStream(upload+"t.jpg"); //讀寫字節(jié)數(shù)組 byte[] bytes = new byte[1024]; int len = 0 ; while((len = in.read(bytes))!=-1){ fos.write(bytes, 0, len); } //通過客戶端連接對象獲取字節(jié)輸出流 //上傳成功寫回客戶端 socket.getOutputStream().write("上傳成功".getBytes()); fos.close(); socket.close(); server.close(); }
}
21TCP圖片上傳問題解決/*
實現(xiàn)TCP圖片上傳客戶端
實現(xiàn)步驟:
Socket套接字連接服務(wù)器
通過Socket獲取字節(jié)輸出流,寫圖片
使用自己的流對象,讀取圖片數(shù)據(jù)源
FileInputStream
讀取圖片,使用字節(jié)輸出流,將圖片寫到服務(wù)器
采用字節(jié)數(shù)組進行緩沖
通過Socket套接字獲取字節(jié)輸入流
讀取服務(wù)器發(fā)回來的上傳成功
關(guān)閉資源
*/
public class TCPClient {
public static void main(String[] args) throws IOException{
Socket socket = new Socket("127.0.0.1", 8000); //獲取字節(jié)輸出流,圖片寫到服務(wù)器 OutputStream out = socket.getOutputStream(); //創(chuàng)建字節(jié)輸入流,讀取本機上的數(shù)據(jù)源圖片 FileInputStream fis = new FileInputStream("c: .jpg"); //開始讀寫字節(jié)數(shù)組 int len = 0 ; byte[] bytes = new byte[1024]; while((len = fis.read(bytes))!=-1){ out.write(bytes, 0, len); } //給服務(wù)器寫終止序列 socket.shutdownOutput();//想服務(wù)端寫入一個結(jié)束標(biāo)志 //獲取字節(jié)輸入流,讀取服務(wù)器的上傳成功 InputStream in = socket.getInputStream(); len = in.read(bytes); System.out.println(new String(bytes,0,len)); fis.close(); socket.close();
}
}
*A:TCP上傳文件名
/*
* TCP圖片上傳服務(wù)器 * 1. ServerSocket套接字對象,監(jiān)聽端口8000 * 2. 方法accept()獲取客戶端的連接對象 * 3. 客戶端連接對象獲取字節(jié)輸入流,讀取客戶端發(fā)送圖片 * 4. 創(chuàng)建File對象,綁定上傳文件夾 * 判斷文件夾存在, 不存,在創(chuàng)建文件夾 * 5. 創(chuàng)建字節(jié)輸出流,數(shù)據(jù)目的File對象所在文件夾 * 6. 字節(jié)流讀取圖片,字節(jié)流將圖片寫入到目的文件夾中 * 7. 將上傳成功會寫客戶端 * 8. 關(guān)閉資源 * */
public class TCPServer {
public static void main(String[] args) throws IOException{ ServerSocket server = new ServerSocket(8000); Socket socket = server.accept(); //通過客戶端連接對象,獲取字節(jié)輸入流,讀取客戶端圖片 InputStream in = socket.getInputStream(); //將目的文件夾封裝到File對象 File upload = new File("d:upload"); if(!upload.exists()) upload.mkdirs(); //防止文件同名被覆蓋,從新定義文件名字 //規(guī)則: 域名+毫秒值+6位隨機數(shù) String filename="itcast"+System.currentTimeMillis()+new Random().nextInt(999999)+".jpg"; //創(chuàng)建字節(jié)輸出流,將圖片寫入到目的文件夾中 FileOutputStream fos = new FileOutputStream(upload+File.separator+filename); //讀寫字節(jié)數(shù)組 byte[] bytes = new byte[1024]; int len = 0 ; while((len = in.read(bytes))!=-1){ fos.write(bytes, 0, len); } //通過客戶端連接對象獲取字節(jié)輸出流 //上傳成功寫回客戶端 socket.getOutputStream().write("上傳成功".getBytes()); fos.close(); socket.close(); server.close(); }
}
多線程上傳案例*A:多線程上傳案例
public class TCPThreadServer {
public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(8000); while (true) { // 獲取到一個客戶端,必須開啟新線程,為這個客戶端服務(wù) Socket socket = server.accept(); new Thread(new Upload(socket)).start(); } }
}
public class Upload implements Runnable {
private Socket socket; public Upload(Socket socket) { this.socket = socket; } public void run() { try { // 通過客戶端連接對象,獲取字節(jié)輸入流,讀取客戶端圖片 InputStream in = socket.getInputStream(); // 將目的文件夾封裝到File對象 File upload = new File("d:upload"); if (!upload.exists()) upload.mkdirs(); // 防止文件同名被覆蓋,從新定義文件名字 // 規(guī)則: 域名+毫秒值+6位隨機數(shù) String filename = "itcast" + System.currentTimeMillis() + new Random().nextInt(999999) + ".jpg"; // 創(chuàng)建字節(jié)輸出流,將圖片寫入到目的文件夾中 FileOutputStream fos = new FileOutputStream(upload + File.separator + filename); // 讀寫字節(jié)數(shù)組 byte[] bytes = new byte[1024]; int len = 0; while ((len = in.read(bytes)) != -1) { fos.write(bytes, 0, len); } // 通過客戶端連接對象獲取字節(jié)輸出流 // 上傳成功寫回客戶端 socket.getOutputStream().write("上傳成功".getBytes()); fos.close(); socket.close(); } catch (Exception ex) { } }
}
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/67179.html
摘要:比如,已知地址和的子網(wǎng)掩碼都是,請問它們是否在同一個子網(wǎng)絡(luò)兩者與子網(wǎng)掩碼分別進行運算,運算得網(wǎng)絡(luò)地址結(jié)果運算得網(wǎng)絡(luò)地址結(jié)果結(jié)果都是,因此它們在同一個子網(wǎng)絡(luò)。 計算機網(wǎng)絡(luò)的發(fā)展及基礎(chǔ)網(wǎng)絡(luò)概念 早期:聯(lián)機 showImg(https://segmentfault.com/img/bVbeG0N?w=980&h=316); 以太網(wǎng):局域網(wǎng)與交換機 showImg(https://segmen...
摘要:代表傳輸控制協(xié)議網(wǎng)際協(xié)議,指的是一系列協(xié)議。,傳輸控制協(xié)議是面向連接的協(xié)議,也就是說,在收發(fā)數(shù)據(jù)前,必須和對方建立可靠的連接。第二是超文本傳輸協(xié)議,信息是明文傳輸,則是具有安全性的加密傳輸協(xié)議。 IP:網(wǎng)絡(luò)層協(xié)議; TCP和UDP:傳輸層協(xié)議; HTTP:應(yīng)用層協(xié)議; SOCKET:TCP/IP網(wǎng)絡(luò)的API。 TCP/IP代表傳輸控制協(xié)議/網(wǎng)際協(xié)議,指的是一系列協(xié)議。 T...
摘要:面向字節(jié)流流,指的是流入到進程或從進程流出的字符序列。即收到連接信息后向返回確認信息第三次握手客戶端收到服務(wù)器的報文段,并向服務(wù)器發(fā)送報文段。 前言 Socket的使用在 Android網(wǎng)絡(luò)編程中非常重要 今天我將帶大家全面了解 Socket 及 其使用方法 目錄 showImg(https://segmentfault.com/img/remote/14600000113508...
閱讀 1487·2021-11-24 11:16
閱讀 2689·2021-07-28 12:32
閱讀 2302·2019-08-30 11:22
閱讀 1440·2019-08-30 11:01
閱讀 595·2019-08-29 16:24
閱讀 3547·2019-08-29 12:52
閱讀 1625·2019-08-29 12:15
閱讀 1332·2019-08-29 11:18