1. 程式人生 > >網絡通信

網絡通信

fse 關閉 其他應用 導致 .so lose send cnblogs println

一 概述

1.網絡模型

OSI(Open System Interconnection,開放式系統互聯)模型,是對網絡系統結構的概括,將網絡分為七層:應用層、表示層、會話層、傳輸層、網絡層、數據鏈路層、物理層。

2.IP協議

網絡層協議,規定了在互聯網上確定與尋找計算機的規則。

3.TCP協議

傳輸層的一種數據傳輸協議,數據傳輸前通過“三次握手”建立連接,然後再發送數據,適用於對數據準確性要求較高的情況,由於數據傳輸前需要建立連接,傳輸速度較慢。

4.UDP協議

傳輸層的一種數據傳輸協議,數據傳輸前不需要建立連接,適用於對數據準確性要求不高的情況,傳輸數據較快,一般

聊天信息都通過該協議傳輸。

5.HTTP協議

HTTP協議屬於應用層協議,為操作系統或網絡應用程序提供訪問網絡服務的接口。

6.端口port

當數據到達計算機後,為了找到目標應用程序,為每一個應用程序分配了一個整數值,取值0-65535,這個整數值就是端口,從中可以看出,端口代表了計算機上一個應用程序,保證數據準確到達預定的程序。一個端口不能同時被多個應用程序占用,一個應用程序結束以後,端口不會立即釋放,有一個內存延遲占有的時間,這個時間一般很短。端口、0-1023已經被系統應用程序及其他應用程序占用,程序設計時避免使用這個範圍的端口。

7.套接字Socket

套接字是數據發送與接收的工具。發送者通過套接字發送數據,接受者通過套接字監聽指定的端口獲取數據。

8.無論采用TCP協議,還是UDP協議,數據都只能以字節形式發送。

二 TCP程序設計

1.關閉通過Socket獲取的輸入流或者輸出流將關閉Socket。

2.通過Socket獲取的輸出流輸出完畢後必須關閉,不然另一端對應的輸入流將阻塞。由於通過輸出流對象關閉輸出流時,同時關閉Socket對象,將導致另一端無法獲取對應Socket的對象,因此只能通過Socket下的方法shutdownOutput關閉輸出流。

3.客戶端的一般步驟:

Socket socket=new Socket(String host,int port);//創建客戶端Socket,發送與接收數據,需要指明服務器IP與端口
OutputStream os=socket.getOutputStream();//獲取輸出流,向服務器發送數據 .......... os.flush(); socket.shutdownOutput();//關閉輸出流,防止服務器端阻塞 InputStream is=socket.getInputStream();//獲取輸入流,輸入流包含服務器的反饋信息 ............ socket.close();//關閉socket,同時關閉輸入與輸出流

4.服務器的一般步驟:

ServerSocket server=new ServerSocket(int port);//建立服務器端套接字,指定監聽端口
Socket socket=server.accept();//獲取訪問客戶端的Socket,阻塞線程
InputStream is=socket.getInputStream();//獲取輸入流,其中包含客戶端發送的數據
.............

OutputStream os=socket.getOutputStream();//獲取輸出流,向客戶端反饋信息
..............
os.flush();
os.shutdownOutput();

server.close();

5.Demo

客戶端

package com.javase.networkCommunication.tcp.demo02;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class ImgClient {

    public static void main(String[] args) throws UnknownHostException, IOException {
        Socket socket = new Socket("192.168.146.1", 10007);
        FileInputStream is = new FileInputStream("Files/1.jpg");
        OutputStream os = socket.getOutputStream();
        byte[] buf = new byte[1024];// 先將數據讀取到緩沖區,比頻繁的從硬盤讀取速度快
        int length = 0;
        while ((length = is.read(buf)) != -1) {
            os.write(buf, 0, length);
        }
        os.flush();
        socket.shutdownOutput();// 如果輸出流不關閉,服務端對應的輸入流會阻塞

        InputStream replyIs = socket.getInputStream();//不會阻塞線程
        byte[] buf01 = new byte[1024];
        int length01 = replyIs.read(buf01);
        String reply = new String(buf01, 0, length01);
        System.out.println(reply);
        
        is.close();
        socket.close();
    }

}

服務器

package com.javase.networkCommunication.tcp.demo02;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import org.junit.Test;

public class ImgServer {

    @Test
    public void test01() throws IOException {
        ServerSocket serverSocket = new ServerSocket(10007);
        Socket socket = serverSocket.accept();// 線程阻塞,等待請求
        System.out.println("hostAddress=" + socket.getInetAddress().getHostAddress());
        InputStream is = socket.getInputStream();
        FileOutputStream os = new FileOutputStream("Files/2.jpg");
        System.out.println(1);
        byte[] buf = new byte[1024];
        int length = 0;
        System.out.println(2);
        int count = 3;
        while ((length = is.read(buf)) != -1) {
            os.write(buf, 0, length);
            System.out.println(count++);
        }
        os.flush();
        os.close();
        System.out.println("圖片上傳結束");

        /*PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        out.write("success");*/
        OutputStream out = socket.getOutputStream();
        out.write("success".getBytes());
        out.flush();
        socket.shutdownOutput();
        System.out.println("響應數據已發出");
        
        serverSocket.close();
    }

}

三 UDP程序設計

1.數據處理方式

UDP協議以數據包的形式發送數據,每個包的最大值64k。

2.發送數據的一般步驟:

DatagramSocket socket=new DatagramSocket();//創建數據報套接字用於發送數據
//DUP協議采用數據包分段發送數據,因此需要建立數據包,在數據包中指明目的地IP與端口
DatagramPacket packet= DatagramPacket(byte buf[], int offset, int length,InetAddress address, int port);
socket.send(packet);

3.接收數據的一般步驟:

DatagramSocket socket=new DatagramSocket(int port);//創建監聽指定端口的數據報套接字
DatagramPacket packet=new DatagramPacket(byte buf[], int length);
socket.receive(packet);


網絡通信