java筆記--網(wǎng)絡(luò)編程

網(wǎng)絡(luò)模型:

OSI參考模型,TCP/IP參考模型。


網(wǎng)絡(luò)通訊要素:
IP地址(InetAddress):

網(wǎng)絡(luò)中設(shè)備的標(biāo)識;
不易記憶,可用主機(jī)名;
本地回環(huán)地址:127.0.0.1;
主機(jī)名:localhost。

public class IPDemo {

    public static void main(String[] args) throws UnknownHostException {
        // 獲取本地主機(jī)ip地址對象
        InetAddress ip=InetAddress.getLocalHost();
        
        //獲取其他主機(jī)IP地址對象
        ip=InetAddress.getByName("192.168.1.105");//InetAddress.getByName("PC-20150505PSNT");
        
        System.out.println(ip.getHostAddress());
        System.out.println(ip.getHostName());
    }
}

運(yùn)行:
端口號:

用于標(biāo)識進(jìn)程的邏輯地址,不同進(jìn)程的標(biāo)識;
有效端口:0-65535,其中0-1024系統(tǒng)使用或保留端口。

傳輸協(xié)議:

通訊的規(guī)則;
常見協(xié)議:TCP,UDP。

UDP:

將數(shù)據(jù)及源和目的封裝在數(shù)據(jù)包中,不需要建立連接;
每個數(shù)據(jù)包的大小限制在64k內(nèi);
因無連接,是不可靠協(xié)議;
不需要建立連接,速度快。

TCP:

建立連接,形成傳輸數(shù)據(jù)的通道;
在連接中進(jìn)行大數(shù)據(jù)量傳輸;
通過三次握手完成連接,是可靠協(xié)議;
必須建立連接,效率會稍低。

Socket:

Scoket就是為網(wǎng)絡(luò)服務(wù)提供的一種機(jī)制;
通信的兩端都有Socket;
網(wǎng)絡(luò)通信其實(shí)就是Socket間的通信;
數(shù)據(jù)在兩個Socket間通過IO傳輸。

UDP傳輸:

DatagramSocket與DatagramPacket;
建立發(fā)送端,接收端;
調(diào)用Socket的發(fā)送接收方法;
關(guān)閉Socket;
發(fā)送端與接收端是兩個獨(dú)立的運(yùn)行程序。

發(fā)送端:在發(fā)送端,要在數(shù)據(jù)包對象中明確目的地IP及端口。
public class UDPSendDemo {

    public static void main(String[] args) throws IOException {
        
        System.out.println("發(fā)送端啟動......");
        /*
        創(chuàng)建UDP傳輸?shù)陌l(fā)送端。
        思路:
        1,建立udp的socket服務(wù)。
        2,將要發(fā)送的數(shù)據(jù)封裝到數(shù)據(jù)包中。
        3,通過udp的socket服務(wù)將數(shù)據(jù)包發(fā)送出去。
        4,關(guān)閉socket服務(wù)。
        */
        //1,udpsocket服務(wù)。使用DatagramSocket對象。
        DatagramSocket ds=new DatagramSocket(8888);//設(shè)置端口號
        
        //2,將要發(fā)送的數(shù)據(jù)封裝到數(shù)據(jù)包中
        String str="laile1laile";
        //使用DatagramPacket將數(shù)據(jù)封裝到該對象中
        byte[] buf=str.getBytes();
        
        DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.105"),10000);
        
        //3,通過udp的socket服務(wù)將數(shù)據(jù)包發(fā)送出去。使用send方法。
        ds.send(dp);
        
        //4,關(guān)閉資源
        ds.close();
    }
}
接收端:在接收端,要指定監(jiān)聽的端口。
public class UDPReceDemo {
    public static void main(String[] args) {
        
        System.out.println("接收端啟動....");
        /*
        建立UDP接收端思路:
        1,建立udp socket服務(wù),因?yàn)槭且邮軘?shù)據(jù),必須明確一個接口號
        2,創(chuàng)建數(shù)據(jù)包,用于存儲接收到的數(shù)據(jù)。方便使用數(shù)據(jù)包對象的方法解析這些數(shù)據(jù)。
        3,使用socket服務(wù)的receive方法將接受的數(shù)據(jù)存儲到數(shù)據(jù)包中。
        4,通過數(shù)據(jù)包對的方法解析數(shù)據(jù)包中的數(shù)據(jù)。
        5,關(guān)閉資源。
        */
        //1,建立udp socket服務(wù)。
        DatagramSocket ds = new DatagramSocket(10000);
        
        
        //2,創(chuàng)建數(shù)據(jù)包。
        byte[] buf = new byte[1024];
        DatagramPacket dp = new DatagramPacket(buf,buf.length);
        
        //3,使用接收方法將數(shù)據(jù)存儲到數(shù)據(jù)包中。
        ds.receive(dp);//阻塞式的。
        
        //4,通過數(shù)據(jù)包對象的方法,解析其中的數(shù)據(jù),比如,地址,端口,數(shù)據(jù)內(nèi)容。
        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();
    }

}

運(yùn)行:

聊天程序:

public class UDPSendDemo2 {

    public static void main(String[] args) throws IOException {
        
        System.out.println("發(fā)送端啟動......");
        /*
        創(chuàng)建UDP傳輸?shù)陌l(fā)送端。
        思路:
        1,建立udp的socket服務(wù)。
        2,將要發(fā)送的數(shù)據(jù)封裝到數(shù)據(jù)包中。
        3,通過udp的socket服務(wù)將數(shù)據(jù)包發(fā)送出去。
        4,關(guān)閉socket服務(wù)。
        */
        //1,udpsocket服務(wù)。使用DatagramSocket對象。
        DatagramSocket ds=new DatagramSocket();//設(shè)置端口號
        
        //2,將要發(fā)送的數(shù)據(jù)封裝到數(shù)據(jù)包中
//      String str="你好,來了";
        BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
        String line=null;
        
        while((line=bufr.readLine())!=null){
            //使用DatagramPacket將數(shù)據(jù)封裝到該對象中
        byte[] buf=line.getBytes();
        
        DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.105"),10000);
        
        //3,通過udp的socket服務(wù)將數(shù)據(jù)包發(fā)送出去。使用send方法。
        ds.send(dp);
        
        if("886".equals(line))
            break;
        }
        
        
        //4,關(guān)閉資源
        ds.close();
    }
}
public class UDPReceDemo2 {

    public static void main(String[] args) throws IOException {

        System.out.println("接收端啟動......");
        /*
         * 建立UDP接收端的思路。
         * 1,建立udp socket服務(wù),因?yàn)槭且邮諗?shù)據(jù),必須要明確一個端口號。
         * 2,創(chuàng)建數(shù)據(jù)包,用于存儲接收到的數(shù)據(jù)。方便用數(shù)據(jù)包對象的方法解析這些數(shù)據(jù).
         * 3,使用socket服務(wù)的receive方法將接收的數(shù)據(jù)存儲到數(shù)據(jù)包中。
         * 4,通過數(shù)據(jù)包的方法解析數(shù)據(jù)包中的數(shù)據(jù)。
         * 5,關(guān)閉資源 
         */
        
        //1,建立udp socket服務(wù)。
        DatagramSocket ds = new DatagramSocket(10000);
        
        while(true){
            //2,創(chuàng)建數(shù)據(jù)包。
        byte[] buf = new byte[1024];
        DatagramPacket dp = new DatagramPacket(buf,buf.length);
        
        //3,使用接收方法將數(shù)據(jù)存儲到數(shù)據(jù)包中。
        ds.receive(dp);//阻塞式的。
        
        //4,通過數(shù)據(jù)包對象的方法,解析其中的數(shù)據(jù),比如,地址,端口,數(shù)據(jù)內(nèi)容。
        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();
        
        
    }

}

運(yùn)行:

基于多線程的小聊天程序:

public class Send implements Runnable {
    
    private DatagramSocket ds;
    
    
    
    public Send(DatagramSocket ds) {
        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();
                DatagramPacket dp = 
                        new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10001);
                ds.send(dp);
                
                if("886".equals(line))
                    break;
            }
            
            ds.close();
        } catch (Exception e) {
        }

    }
}
public class Rece implements Runnable {
    
    private DatagramSocket ds;
    
    public Rece(DatagramSocket ds) {
        this.ds = ds;
    }



    @Override
    public void run() {
        try {
            while (true) {

                // 2,創(chuàng)建數(shù)據(jù)包。
                byte[] buf = new byte[1024];
                DatagramPacket dp = new DatagramPacket(buf, buf.length);

                // 3,使用接收方法將數(shù)據(jù)存儲到數(shù)據(jù)包中。
                ds.receive(dp);// 阻塞式的。

                // 4,通過數(shù)據(jù)包對象的方法,解析其中的數(shù)據(jù),比如,地址,端口,數(shù)據(jù)內(nèi)容。
                String ip = dp.getAddress().getHostAddress();
                int port = dp.getPort();
                String text = new String(dp.getData(), 0, dp.getLength());
                
                System.out.println(ip + "::" + text);
                if(text.equals("886")){
                    System.out.println(ip+"....退出聊天室");
                }

            }
        } catch (Exception e) {

        }

    }
}
public class ChatDemo {

    public static void main(String[] args) throws IOException {
        
        DatagramSocket send=new DatagramSocket();
        
        DatagramSocket rece=new DatagramSocket(10001);
        
        new Thread(new Send(send)).start();
        new Thread(new Rece(rece)).start();
    }
}

運(yùn)行:
TCP傳輸:

Socket和ServerSocket;
建立客戶端和服務(wù)器;
建立連接后,通過Socket中的IO流進(jìn)行數(shù)據(jù)的傳輸;
關(guān)閉socket;
同樣,客戶端與服務(wù)器是兩個獨(dú)立的應(yīng)用程序。

基本思路(客戶端):

客戶端需要明確服務(wù)器的ip地址以及端口,這樣才可以去試著建立連接,如果連接失敗,會出現(xiàn)異常;
連接成功,說明客戶端與服務(wù)端建立了通道,那么通過IO流就可以進(jìn)行數(shù)據(jù)的傳輸,而Socket對象已經(jīng)提供了輸入流和輸出流對象,通過getInputStream(),getOutputStream()獲取即可;
與服務(wù)端通訊結(jié)束后,關(guān)閉Socket。

基本思路(服務(wù)端):

服務(wù)端需要明確它要處理的數(shù)據(jù)是從哪個端口進(jìn)入的;
當(dāng)有客戶端訪問時,要明確是哪個客戶端,可通過accept()獲取已連接的客戶端對象,并通過該對象與客戶端通過IO流進(jìn)行數(shù)據(jù)傳輸;
當(dāng)該客戶端訪問結(jié)束,關(guān)閉該客戶端。

客戶端:

通過Socket建立對象并指定要連接的服務(wù)端主機(jī)以及端口。

public class ClientDemo {

    public static void main(String[] args) throws UnknownHostException, IOException {
        //客戶端發(fā)送數(shù)據(jù)到服務(wù)端
        /*
        tcp傳輸,客戶端建立的過程:
        1,創(chuàng)建tcp客戶端socket服務(wù)。使用的是Socket對象。
            建議該對象一創(chuàng)建就明確目的地--要連接的主機(jī)。
        2,如果連接建立成功,說明數(shù)據(jù)傳輸通道已建立。
            該通道就是socket流,是底層建立好的。既然是流,就有輸入和輸出。
            想要輸入或者輸出流對象,可以找Socket來獲取。
            可以通過getOutputStream和getInutStream來獲取兩個字節(jié)流。
        3,使用輸出流,將數(shù)據(jù)寫出
        4,關(guān)閉資源
        */
        //創(chuàng)建客戶端socket服務(wù)
        Socket socket=new Socket("192.168.1.105",10002);
        
        //獲取socket流中的輸出流
        OutputStream out=socket.getOutputStream();
        
        //使用輸出流將指定的數(shù)據(jù)寫出去
        out.write("又來了".getBytes());
        
        //關(guān)閉資源
        socket.close();
    }

}
服務(wù)端:

建立服務(wù)端需要監(jiān)聽一個端口。

public class ServerDemo {

    public static void main(String[] args) throws IOException {
        //服務(wù)端接收客戶端發(fā)送過來的數(shù)據(jù),并打印在控制臺上
        /*
        建立tcp服務(wù)端的思路:
        1,創(chuàng)建服務(wù)端socket服務(wù)。通過ServerSocket對象。
        2,服務(wù)端必須對外提供一個端口,否則客戶端無法連接。
        3,獲取連接過來的客戶端對象。
        4,通過客戶端對象獲取socket流讀取客戶端發(fā)來的數(shù)據(jù)并打印在控制臺上。
        5,關(guān)閉資源。關(guān)客戶端,關(guān)服務(wù)端。
        */
        //1,創(chuàng)建服務(wù)端對象
        ServerSocket ss=new ServerSocket(10002);
        
        //2,獲取連接過來的客戶端對象
        Socket s=ss.accept();
        
        String ip=s.getInetAddress().getHostAddress();
        
        //3,通過socket對象獲取輸入流,要讀取客戶端發(fā)來的數(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(ip+":"+text);
        
        s.close();
        ss.close();
    }

}

運(yùn)行:
public class ClientDemo2 {

    public static void main(String[] args) throws UnknownHostException, IOException {
        //客戶端發(fā)送數(shù)據(jù)到服務(wù)端
        /*
        tcp傳輸,客戶端建立的過程:
        1,創(chuàng)建tcp客戶端socket服務(wù)。使用的是Socket對象。
            建議該對象一創(chuàng)建就明確目的地--要連接的主機(jī)。
        2,如果連接建立成功,說明數(shù)據(jù)傳輸通道已建立。
            該通道就是socket流,是底層建立好的。既然是流,就有輸入和輸出。
            想要輸入或者輸出流對象,可以找Socket來獲取。
            可以通過getOutputStream和getInutStream來獲取兩個字節(jié)流。
        3,使用輸出流,將數(shù)據(jù)寫出
        4,關(guān)閉資源
        */
        //創(chuàng)建客戶端socket服務(wù)
        Socket socket=new Socket("192.168.1.105",10002);
        
        //獲取socket流中的輸出流
        OutputStream out=socket.getOutputStream();
        
        //使用輸出流將指定的數(shù)據(jù)寫出去
        out.write("又來了".getBytes());
        
        //讀取服務(wù)端返回的數(shù)據(jù),使用socket讀取流
        InputStream in=socket.getInputStream();
        byte[] buf=new byte[1024];
        
        int len=in.read(buf);
        
        String text=new String(buf,0,len);
        System.out.println(text);
        
        //關(guān)閉資源
        socket.close();
    }
}
public class ServerDemo2 {

    public static void main(String[] args) throws IOException {
        //服務(wù)端接收客戶端發(fā)送過來的數(shù)據(jù),并打印在控制臺上
        /*
        建立tcp服務(wù)端的思路:
        1,創(chuàng)建服務(wù)端socket服務(wù)。通過ServerSocket對象。
        2,服務(wù)端必須對外提供一個端口,否則客戶端無法連接。
        3,獲取連接過來的客戶端對象。
        4,通過客戶端對象獲取socket流讀取客戶端發(fā)來的數(shù)據(jù)并打印在控制臺上。
        5,關(guān)閉資源。關(guān)客戶端,關(guān)服務(wù)端。
        */
        //1,創(chuàng)建服務(wù)端對象
        ServerSocket ss=new ServerSocket(10002);
        
        //2,獲取連接過來的客戶端對象
        Socket s=ss.accept();
        
        String ip=s.getInetAddress().getHostAddress();
        
        //3,通過socket對象獲取輸入流,要讀取客戶端發(fā)來的數(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(ip+":"+text);
        
        
        //使用客戶端socket對象的輸出流給客戶端返回數(shù)據(jù)
        OutputStream out=s.getOutputStream();
        out.write("收到".getBytes());
        
        s.close();
        ss.close();
    }
}

運(yùn)行:
Tcp傳輸最容易出現(xiàn)的問題:

客戶端連接上服務(wù)端,兩端都在等待,沒有任何數(shù)據(jù)傳輸。
通過例程分析: 因?yàn)閞ead方法或者readLine方法是阻塞式。
解決方法:自定義結(jié)束標(biāo)記,使用shutdownInput,shutsownOutput方法。

字母大小寫轉(zhuǎn)換服務(wù)器:
public class TransClient {

    public static void main(String[] args) throws UnknownHostException, IOException {
        // 客戶端
        /*
        思路:
        1,有socket端點(diǎn)
        2,數(shù)據(jù)源--鍵盤
        3,目的--socket
        4,接收服務(wù)器的數(shù)據(jù)--源:socket
        5,將數(shù)據(jù)顯示再打印出來--目的:控制臺
        6,在這些流中操作的數(shù)據(jù),都是文本數(shù)據(jù)
        
        轉(zhuǎn)換客戶端:
        1,創(chuàng)建socket客戶端對象
        2,獲取鍵盤錄入
        3,將錄入的信息發(fā)送給socket輸出流
        */
        //1,創(chuàng)建socket客戶端對象
        Socket s=new Socket("192.168.1.105",10004);
        
        //2,獲取鍵盤錄入
        BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
        
        //3,socket輸出流
//      new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        PrintWriter out=new PrintWriter(s.getOutputStream(),true);//true:開啟自動刷新
        
        //4,socket輸入流,讀取服務(wù)端返回的大寫數(shù)據(jù)
        BufferedReader bufIn=new BufferedReader(new InputStreamReader(s.getInputStream()));
        
        String line=null;
        
        while((line=bufr.readLine())!=null){
            if("over".equals(line))
                break;
//          out.print(line+"\r\n");
//          out.flush();
            out.println(line);
            
            //讀取服務(wù)端發(fā)回的一行大寫數(shù)據(jù)
            String upperStr=bufIn.readLine();
            System.out.println(upperStr);
        }
        s.close();
        
    }
}
public class TransServer {

    public static void main(String[] args) throws IOException {
        /*
        轉(zhuǎn)換服務(wù)端
        分析:
        1,serversocket服務(wù)
        2,獲取socket對象
        3,源:socket,讀取客戶端發(fā)過來的需要轉(zhuǎn)換的數(shù)據(jù)
        4,目的:顯示在控制臺上
        5,將數(shù)據(jù)轉(zhuǎn)成大寫發(fā)給客戶端
        */
        ServerSocket ss=new ServerSocket(10004);
        
        Socket s=ss.accept();
        
        String ip=s.getInetAddress().getHostAddress();
        System.out.println(ip+"......connected");
        
        BufferedReader bufIn=new BufferedReader(new InputStreamReader(s.getInputStream()));
        
        PrintWriter out=new PrintWriter(s.getOutputStream(),true);
        
        String line=null;
        while((line=bufIn.readLine())!=null){
            System.out.println(line);
            out.println(line.toUpperCase());
//          out.println(line.toUpperCase()+"\r\n");
//          out.flush();
        }
        s.close();
        ss.close();
    }
}

運(yùn)行:
客戶端上傳文本到服務(wù)器:
public class UploadServer {

    public static void main(String[] args) throws IOException {
        System.out.println("上傳服務(wù)端。。。。。。。。。");
        
        ServerSocket ss = new ServerSocket(10005);
        
        Socket s = ss.accept();
        
        System.out.println(s.getInetAddress().getHostAddress()+".....connected");
        
        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
        
        BufferedWriter bufw = new BufferedWriter(new FileWriter("d:\\server.txt"));
        
        String line = null;
        
        while((line=bufIn.readLine())!=null){
            
//          if("over".equals(line))
//              break;
            bufw.write(line);
            bufw.newLine();
            bufw.flush();
        }
        
        
        PrintWriter out = new PrintWriter(s.getOutputStream(),true);
        out.println("上傳成功");
        
        bufw.close();
        
        s.close();
        ss.close(); 
    }
}
public class UploadClient {

    public static void main(String[] args) throws UnknownHostException, IOException {

        System.out.println("上傳客戶端。。。。。。");
        
        /*File file = new File("d:\\client.txt");
        System.out.println(file.exists());*/
        
        
        Socket s = new Socket("192.168.1.105",10005);
        
        BufferedReader bufr =
                new BufferedReader(new FileReader("d:\\client.txt"));
        
        PrintWriter out = new PrintWriter(s.getOutputStream(),true);
        
        
        String line = null;
        while((line=bufr.readLine())!=null){
            
            out.println(line);
        }
        
        //告訴服務(wù)端,客戶端寫完了。
        s.shutdownOutput();
//      out.println("!@#$%^&*(");
        
        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
        
        String str = bufIn.readLine();
        System.out.println(str);
        
        bufr.close();
        s.close();
        
    }

}

運(yùn)行:

上傳圖片:
public class UploadTask implements Runnable {
    
    private static final int SIZE=1024*1024*8;
    
    private Socket s;
    
    public UploadTask(Socket s) {
        this.s = s;
    }
    
    @Override
    public void run() {
        
        int count = 0;
        String ip = s.getInetAddress().getHostAddress();
        System.out.println(ip + ".....connected");
        
        try{

        // 讀取客戶端發(fā)來的數(shù)據(jù)。
        InputStream in = s.getInputStream();

        // 將讀取到數(shù)據(jù)存儲到一個文件中。
        File dir = new File("c:\\pic");
        if (!dir.exists()) {
            dir.mkdirs();
        }
        File file = new File(dir, ip + ".jpg");
        //如果文件已經(jīng)存在于服務(wù)端 
        while(file.exists()){
            file = new File(dir,ip+"("+(++count)+").jpg");
        }
        
        
        FileOutputStream fos = new FileOutputStream(file);

        byte[] buf = new byte[1024];

        int len = 0;

        while ((len = in.read(buf)) != -1) {
            
            
            
            fos.write(buf, 0, len);
            
            if(file.length()>SIZE){
                System.out.println(ip+"文件體積過大");
                
                fos.close();
                s.close();
                
                
                System.out.println(ip+"...."+file.delete());
                
                return ;
            }
        }

        // 獲取socket輸出流,將上傳成功字樣發(fā)給客戶端。
        OutputStream out = s.getOutputStream();
        out.write("上傳成功".getBytes());
        
        fos.close();
        s.close();
        } catch (IOException e) {
            
        }
    }
}
public class UploadPicServer {

    public static void main(String[] args) throws IOException {
        
        //創(chuàng)建tcp的socket服務(wù)端
        ServerSocket ss=new ServerSocket(10006);
        
        while(true){
            Socket s=ss.accept();
            
            new Thread(new UploadTask(s)).start();
        }
    }
}
public class UploadPicClient {

    public static void main(String[] args) throws UnknownHostException, IOException {
        
        //創(chuàng)建客戶端socket
        Socket s=new Socket("192.168.1.105",10006);
        
        //讀取客戶端要上傳的圖片文件
        FileInputStream fis=new FileInputStream("c:\\0.jpg");
        
        //獲取socket輸出流,將讀到的圖片數(shù)據(jù)發(fā)送給服務(wù)端
        OutputStream out=s.getOutputStream();
        
        byte[] buf=new byte[1024];
        
        int len=0;
        
        while((len=fis.read(buf))!=-1){
            out.write(buf,0,len);
        }
        
        //告訴服務(wù)端數(shù)據(jù)發(fā)送完畢,讓服務(wù)器停止讀取
        s.shutdownInput();
        
        //讀取服務(wù)端發(fā)回的內(nèi)容
        InputStream in=s.getInputStream();
        byte[] bufIn=new byte[1024];
        
        int lenIn=in.read();
        String text=new String(buf,0,lenIn);
        System.out.println(text);
        
        fis.close();
        s.close();
    }
}

運(yùn)行:
模擬Tomcat:
public class MyTomcat {

    public static void main(String[] args) throws IOException {
        
        ServerSocket ss=new ServerSocket(8889);//設(shè)置端口
        
        Socket s=ss.accept();
        System.out.println(s.getInetAddress().getHostAddress()+"....connect");
        
        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);
        
        //給客戶端一個反饋信息
        PrintWriter out=new PrintWriter(s.getOutputStream(),true);
        
        out.println("<font color='red' size='7'>歡迎光臨</font>z");
        
        s.close();
        ss.close();

    }
}

運(yùn)行:

可在瀏覽器中輸入(IP地址:8889)回顯數(shù)據(jù)。

模擬瀏覽器:
public class MyBrowser {

    public static void main(String[] args) throws UnknownHostException, IOException {
        
        Socket s=new Socket("192.168.1.105",8080);
        
        //模擬瀏覽器,給tomcat服務(wù)端發(fā)送符合http協(xié)議的請求消息
        PrintWriter out=new PrintWriter(s.getOutputStream(),true);
        out.println("GET /myweb/1.html HTTP/1.1");
        out.println("Accept: */*");
        out.println("Host: 192.168.1.105:8080");
        out.println("Connection: close");
        out.println();
        out.println();
        
        InputStream in=s.getInputStream();
        
        byte[] buf=new byte[1024];
        int len=in.read(buf);
        
        String str=new String(buf,0,len);
        System.out.println(str);
        
        s.close();

    }

}

運(yùn)行:
image.png
URL和URLConnection:
public class URLDemo {

    public static void main(String[] args) throws IOException {
        
        String str_url="http://192.168.1.105:8080/myweb/1.html?name=lisi";
        
        URL url=new URL(str_url);
        
        System.out.println("getProtocol:"+url.getProtocol());
        System.out.println("getHost:"+url.getHost());
        System.out.println("getPort:"+url.getPort());
        System.out.println("getFile:"+url.getFile());
        System.out.println("getPath:"+url.getPath());
        System.out.println("getQuery:"+url.getQuery());
    }

}

運(yùn)行:
public class URLDemo {

    public static void main(String[] args) throws IOException {
        
        String str_url="http://192.168.1.105:8080/myweb/1.html?name=lisi";
        
        URL url=new URL(str_url);
        
        InputStream in=url.openStream();
        
        byte[] buf=new byte[1024];
        int len=in.read(buf);
        
        String text=new String(buf,0,len);
        
        System.out.println(text);
        
        in.close();
    }

}

運(yùn)行:
public class URLDemo {

    public static void main(String[] args) throws IOException {
        
        String str_url="http://192.168.1.105:8080/myweb/1.html?name=lisi";
        
        URL url=new URL(str_url);
        
        //獲取url對象的Url連接器對象。將連接封裝成了對象:java內(nèi)置的可以解析的具體協(xié)議對象+socket
        URLConnection conn=url.openConnection();
        String value=conn.getHeaderField("Content-Type");
        System.out.println(value);
        
        InputStream in=conn.getInputStream();
        
        byte[] buf=new byte[1024];
        int len=in.read(buf);
        
        String text=new String(buf,0,len);
        
        System.out.println(text);
        
        in.close();
    }

}

運(yùn)行:
網(wǎng)絡(luò)結(jié)構(gòu):

C/S --client/server:
特點(diǎn):該結(jié)構(gòu)的軟件,客戶端和服務(wù)端都需要編寫,可開發(fā)成本較高,維護(hù)較為麻煩。
好處:客戶端在本地可以分擔(dān)一部分運(yùn)算。

B/S--browsr/server:
特點(diǎn):該結(jié)構(gòu)的軟件,只開發(fā)服務(wù)器端,客戶端直接由瀏覽器取代。開發(fā)成本較低,維護(hù)更為簡單。
缺點(diǎn):所有運(yùn)算都要在服務(wù)端完成。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 計算機(jī)網(wǎng)絡(luò)概述 網(wǎng)絡(luò)編程的實(shí)質(zhì)就是兩個(或多個)設(shè)備(例如計算機(jī))之間的數(shù)據(jù)傳輸。 按照計算機(jī)網(wǎng)絡(luò)的定義,通過一定...
    蛋炒飯_By閱讀 1,377評論 0 10
  • 網(wǎng)絡(luò)編程 網(wǎng)絡(luò)編程對于很多的初學(xué)者來說,都是很向往的一種編程技能,但是很多的初學(xué)者卻因?yàn)楹荛L一段時間無法進(jìn)入網(wǎng)絡(luò)編...
    程序員歐陽閱讀 2,113評論 1 37
  • 網(wǎng)絡(luò)編程的概述 網(wǎng)絡(luò)編程的實(shí)質(zhì)就是用來實(shí)現(xiàn)網(wǎng)絡(luò)互連的不同計算機(jī)上運(yùn)行的程序間可以進(jìn)行數(shù)據(jù)交換。 一.OSI網(wǎng)絡(luò)模型...
    思念揮霍閱讀 441評論 0 0
  • 1.網(wǎng)絡(luò)編程1.1計算機(jī)網(wǎng)絡(luò)概述網(wǎng)絡(luò)編程的實(shí)質(zhì)就是兩個(或多個)設(shè)備(例如計算機(jī))之間的數(shù)據(jù)傳輸。按照計算機(jī)網(wǎng)絡(luò)的...
    任振銘閱讀 477評論 0 1
  • 小寶寶第一次發(fā)燒,20180722下午。 22晚~23號早上,每隔一個小時水銀測體溫,緊張,心慌。溫度高了擔(dān)心,低...
    theBigVivi閱讀 164評論 0 0

友情鏈接更多精彩內(nèi)容