1. 網絡編程學習1.1. 擴展知識點網絡協議OSI協議:網絡協議的劃分學習1.2. 網絡協議那些事
五層協議模型
網絡協議按照5層劃分可以分為5層:物理層、數據鏈路層、網絡層,傳輸層,應用層。每一層都有一定的協議標準定義。物理層:物理層的協議是根據硬件傳輸數據的特性制定的協議java上傳圖片到服務器,由于光纖,電線只能傳輸0和1二進制數字,物理層的協議有,,,這一層只傳輸二進制數據。數據鏈路層:數據鏈路層是對電信號用來分組的,比如物理層傳來一組數據01,我們可以把它8個分成一組,16個分成一組,剛開始時,各個公司都有自己的分組格式,后來國際上統一了標準,將一組電信號稱為一個數據包,或者叫一個幀,每一個數據幀分成報頭head和數據data兩部分。head包含18個字節,包含==發送者(源地址,6個字節)== ,==接收者(目標地址,6個字節)== ,數據類型(6個字節)data包含最短46個字節,最長1500個字節)數據鏈路層是對數據進行了簡單的封裝,用于方便傳輸數據,解析數據。但是當傳輸時有一個問題,當處于局域網時,也就是在同一個ip網關內的不同主機可以直接傳輸數據,但是如果不同網關的主機如何實現通信?==注意:在同一個網關內主機之間的通信是靠廣播的方式尋找對方的。== 不在同一個網關內,廣播就失效了。這就引出了網絡層的協議。網絡層:網絡層有IP協議,如果傳輸的數據不在同一個網關內,就要需要IP協議了,它是整個OSI協議的核心。只有通過配置IP才能準確獲得目標計算機的Mac地址。應用層:包含的協議就多了,包含HTTP協議,FTP協議,SMTP協議等。主要用于應用層開發。但是HTTP協議需要TCP協議的支持。1.3. 應用之間通信需要對方的ip地址,需要對方應用的邏輯端口號,端口號要綁定應用。
下方是我個人專欄,歡迎關注:
1.4. 網絡編程類類1.5. UDP協議和TCP協議UDP協議:無連接通信協議,無論對方是否在線,都可以發送,比如qq的離線發送。不過不安全,會丟數據,例如廣播產生卡頓等。好處是傳播速度快。消耗資源小。效率高。比如手機發短信,qq發消息。UDP協議會對傳輸數據大小進行限制,只能傳輸協議:面向連接的通信協議,先建立連接java上傳圖片到服務器,才能發送數據。安全性高,速度慢。連接必須經過三次握手。1.6. UDP通信實現UDP協議的發送端:實現步驟:
1public static void main(String[] args) throws IOException {
2 //創建數據包對象,封裝要發送的數據,接收端Ip,端口號
3 byte[] data="123udp".getBytes();
4 //創建一個InetAddress對象,封裝自己的Ip地址
5 InetAddress inetAddress =InetAddress.getByName("127.0.0.1");
6 DatagramPacket dp =new DatagramPacket(data, data.length,inetAddress,8899);
7 //創建DatagramSocket對象,
8 DatagramSocket datagramSocket=new DatagramSocket();
9 datagramSocket.send(dp);
10 datagramSocket.close();
11}
實現UDP接收端實現步驟:
1public static void main(String[] args) throws IOException {
2 //創建數據包傳輸對象,并綁定端口號
3 DatagramSocket ds =new DatagramSocket(8899);
4 //創建字節數組
5 byte[] buf=new byte[1024];
6 //創建數據包對象傳遞字節數組
7 DatagramPacket dp =new DatagramPacket(buf, buf.length);
8 //調用ds的receive傳遞數組
9 ds.receive(dp);
10 String ip =dp.getAddress().getHostAddress();

11 int port =dp.getPort();
12 int length=dp.getLength();
13 System.out.println(new String(buf,0,length)+"..."+ip+"..."+port);
14 ds.close();
15}
發送端實現不間斷的輸入發送數據
1public static void main(String[] args) throws IOException {
2 Scanner sc=new Scanner(System.in);
3 DatagramSocket datagramSocket=new DatagramSocket();
4 InetAddress inetAddress =InetAddress.getByName("127.0.0.1");
5 while(true){
6 String message=sc.nextLine();
7 byte[] data=message.getBytes();
8 DatagramPacket dp =new DatagramPacket(data, data.length,inetAddress,8899);
9 datagramSocket.send(dp);
10 }
11}
實現永不停歇的接收端
1public static void main(String[] args) throws IOException {
2 //創建數據包傳輸對象,并綁定端口號
3 DatagramSocket ds =new DatagramSocket(8899);
4 //創建字節數組
5 byte[] buf=new byte[1024];
6 //創建數據包對象傳遞字節數組
7 while(true){
8 DatagramPacket dp =new DatagramPacket(buf, buf.length);
9 //調用ds的receive傳遞數組
10 ds.receive(dp);

11 String ip =dp.getAddress().getHostAddress();
12 int port =dp.getPort();
13 int length=dp.getLength();
14 System.out.println(new String(buf,0,length)+"..."+ip+"..."+port);
15 }
16}
1.7. TCP通信TCP通信和UDP通信大致相同,分為客戶端和服務端,但是TCP通信是需要先進行連接的,只有連接成功才能通信,不過TCP建立連接后,也就建立了IO流,可以通過IO流完成數據的傳輸。TCP客戶端程序的類 .:構造方法有:( host,int port)用于傳遞服務器Ip和端口號。該構造方法只要運行就會和服務器連接,如果連接失敗就會拋出異常。類有兩個方法,(),返回類型是(),返回套接字的輸出流:作用是將數據輸出,輸出到服務器。(),返回套接字的輸入流,返回類型是.這些方法都是從中獲取的,不是new出來的。
1public static void main(String[] args) throws IOException {
2 Socket socket=new Socket("120.27.60.73", 8899);
3 OutputStream outStream=socket.getOutputStream();
4 outStream.write("789456".getBytes());
5 socket.close();
6}
端:表示服務器程序的類:.,構造方法有:(int port)傳遞端口號,相當于監聽該端口號。一個很重要的事情是,由于多個客戶端向服務端傳值,服務端無法辨認是哪個客戶端發來的值,解決方法是:必須獲取客戶端的套接字對象,用()方法獲取,返回類型是
1public static void main(String[] args) throws IOException {
2 ServerSocket serverSocket=new ServerSocket(8899);
3 Socket socket=serverSocket.accept();
4 InputStream inputStream=socket.getInputStream();
5 byte[] buf=new byte[1024];
6 int len=inputStream.read(buf);
7 System.out.println(new String(buf,0,len));
8 //服務器返回數據
9 OutputStream out=socket.getOutputStream();
10 out.write("nihao".getBytes());
11 socket.close();
12 serverSocket.close();
13}
1.8. TCP通信圖片上傳服務器多線程解決方案TCP通信圖片上傳客戶端代碼
多線程解決方案
1public class TCPClient {
2 public static void main(String[] args) throws IOException{
3 Socket socket = new Socket("127.0.0.1", 8000);
4 //獲取字節輸出流,圖片寫到服務器
5 OutputStream out = socket.getOutputStream();
6 //創建字節輸入流,讀取本機上的數據源圖片
7 FileInputStream fis = new FileInputStream("c:\\t.jpg");
8 //開始讀寫字節數組
9 int len = 0 ;
10 byte[] bytes = new byte[1024];
11 while((len = fis.read(bytes))!=-1){
12 out.write(bytes, 0, len);
13 }
14 //給服務器寫終止序列
15 socket.shutdownOutput();
16
17 //獲取字節輸入流,讀取服務器的上傳成功
18 InputStream in = socket.getInputStream();
19
20 len = in.read(bytes);
21 System.out.println(new String(bytes,0,len));
22
23 fis.close();
24 socket.close();
25 }
26}
將上傳文件接收代碼放到一個線程中。這樣就保證一個線程接收一個。
1public class Upload implements Runnable{
2
3 private Socket socket;
4
5 public Upload(Socket socket){this.socket=socket;}
6
7 public void run() {
8 try{
9 //通過客戶端連接對象,獲取字節輸入流,讀取客戶端圖片
10 InputStream in = socket.getInputStream();
11 //將目的文件夾封裝到File對象
12 File upload = new File("d:\\upload");
13 if(!upload.exists())
14 upload.mkdirs();
15
16 //防止文件同名被覆蓋,從新定義文件名字
17 //規則: 域名+毫秒值+6位隨機數
18 String filename="itcast"+System.currentTimeMillis()+new Random().nextInt(999999)+".jpg";
19 //創建字節輸出流,將圖片寫入到目的文件夾中
20 FileOutputStream fos = new FileOutputStream(upload+File.separator+filename);
21 //讀寫字節數組
22 byte[] bytes = new byte[1024];
23 int len = 0 ;
24 while((len = in.read(bytes))!=-1){
25 fos.write(bytes, 0, len);
26 }
27 //通過客戶端連接對象獲取字節輸出流

28 //上傳成功寫回客戶端
29 socket.getOutputStream().write("上傳成功".getBytes());
30
31 fos.close();
32 socket.close();
33 }catch(Exception ex){
34
35 }
36 }
37
38}
服務器端,調用,并將作為參數傳遞給類。并開啟一個新線程。并讓服務端永久的監聽端口。
1public class TCPThreadServer {
2 public static void main(String[] args) throws IOException{
3 ServerSocket server = new ServerSocket(8000);
4 while(true){
5 //獲取到一個客戶端,必須開啟新線程
6 Socket socket = server.accept();
7 new Thread( new Upload(socket) ).start();
8 }
9
10 }
11}
1.9. 一些技巧公司域名+毫秒值+隨機六位數,防止文件重名
1String fileName="xdclass"+System.currentTimeMillis()+new Ranadow.nextInt(999999)+".jpg";
File.,跨系統生成目錄分隔符。
1File myFile = new File("C:" + File.separator + "tmp" + File.separator, "test.txt");
此外還有File.生成字符分號;2,3總結:File類的兩個常量,一個是斜杠,一個是分號。