java 网络编程

来源:互联网 发布:幼儿园大班美工作品 编辑:程序博客网 时间:2024/06/07 06:32

1. 网络模型:

  • OSI参考模型:(应用层,表示层,会话层,传输层,网络层,数据链路层,物理层)
  • TCP/IP参考模型:(应用层,传输层,网际层,主机至网络层)

2. 网络通讯要素

IP地址

本地回环地址:127.0.0.1,主机名:localhost

端口

可用端口:0~65535,其中0~1024是系统使用或者保留端口。

3. Java网络编程常见对象

3.1 根据主机名获取IP地址

//通过主机名获取对应的IP地址    static void netAddressTest1() throws UnknownHostException{        InetAddress inetAddress=InetAddress.getByName("www.baidu.com");        System.out.println("ip地址是"+inetAddress.getHostAddress());    }

4. UDP和TCP的特点

4.1 UDP

  • 将数据及源和目的封装成数据包,不许要建立连接。

  • 每个数据包的大小限制在64K内。

  • 因无连接,是不可靠协议。

  • 不需要建立连接,速度快。

4.2 TCP

  • 建立连接,形成传输数据的通道。

  • 在连接中进行大数据量传输。

  • 通过三次握手完成连接,是可靠协议。

  • 必须建立连接,效率会稍低。

- 5. UDP的发送和接收

UDP的发送和接收涉及到两个类:DatagramSocket,DatagramPacket。

DatagramSocket是一个Socket,发送方可以指定数据发出去时的端口,也可以不指定,会自动分配。接收方的DatagramSocket需要指定那个端口用来接收数据。(目的和源端口必须一致)

DatagramPacket是数据的载体。发送方的DatagramPacket在创建时需要明确接收方的IP地址和端口。

5.1 简单发送

指明接收方的IP和端口,本机用来发送数据的端口,可指定也可不指定。

将发送的数据填充到byte[]数组里面,然后用该数组构建一个DatagramPacket对象。

代码:

    static void udpSend1() throws Exception{        String hostName="127.0.0.1";        //创建DatagramSocket对象        DatagramSocket datagramSocket=new DatagramSocket();        byte[]datas="haha".getBytes();        //构建DatagramPacket类,其封装了要发送的数据和目的地信息        DatagramPacket datagramPacket=new DatagramPacket(datas, datas.length,InetAddress.getByName(hostName),9999);        //发送        datagramSocket.send(datagramPacket);        //关闭资源        datagramSocket.close();    }

5.2 简单接收

创建DatagramSocket对象时,必须明确那个端口用来接收数据。

创建一个空的字节数组用来接受数据,根据此字节数组创建DatagramPacket对象。

DatagramSocket的receive()方法是阻塞式的。

代码:

    static void udpReceive()throws Exception{        //创建Socket,并且必须指明那个端口用来接收消息        DatagramSocket socket=new DatagramSocket(9999);        //创建字节数组,存储数据        byte[] data=new byte[1024];        DatagramPacket packet=new DatagramPacket(data, data.length);        //接收数据,此方法是阻塞式的,若没有收到消息,会一直等待。        socket.receive(packet);        //得到接收到的数据        String datas=new String(packet.getData(),0,packet.getLength());        //得到发送方用来返送数据的端口        int sendPort=packet.getPort();        //得到发送发的IP地址        String sendIP=packet.getAddress().getHostAddress();        System.out.println("收到的数据是 "+datas+"源端口是 "+sendPort+"源IP是 "+sendIP);        socket.close();    }

5.3 发送端从键盘输入,接收端一直监听

代码:(键盘接收消息发送)

    static void udpSendBykeyBoard() throws Exception{        String hostName="127.0.0.1";        //创建DatagramSocket对象        DatagramSocket datagramSocket=new DatagramSocket();        //System.in从键盘录入        BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));        String datas=null;        //readLine()是阻塞式的,所以不会造成死循环        while((datas=reader.readLine())!=null){            if(datas.equals("over"))                break;            byte[] bytes=datas.getBytes();            //构建DatagramPacket类,其封装了要发送的数据和目的地信息            DatagramPacket datagramPacket=new DatagramPacket(bytes, bytes.length,InetAddress.getByName(hostName),9999);            //发送            datagramSocket.send(datagramPacket);        }        //关闭资源        datagramSocket.close();    }

代码:(接收端一直处于接收状态)

    static void udpReceive()throws Exception{        //创建Socket,并且必须指明那个端口用来接收消息        DatagramSocket socket=new DatagramSocket(9999);        while(true){            //创建字节数组,存储数据            byte[] data=new byte[1024];            DatagramPacket packet=new DatagramPacket(data, data.length);            //接收数据,此方法是阻塞式的,若没有收到消息,会一直等待。            socket.receive(packet);            //得到接收到的数据            String datas=new String(packet.getData(),0,packet.getLength());            //得到发送方用来返送数据的端口            int sendPort=packet.getPort();            //得到发送发的IP地址            String sendIP=packet.getAddress().getHostAddress();            System.out.println("收到的数据是 "+datas+"源端口是 "+sendPort+"源IP是 "+sendIP);        }        //socket.close();    }

5.4 用UDP发送和接收文本文件。

发送代码:

    static void udpSendFile()throws Exception{        String hostName="127.0.0.1";//目标端口        DatagramPacket packet=null;        InetAddress address=InetAddress.getByName(hostName);        DatagramSocket socket=new DatagramSocket();        //创建字符缓冲读出流        BufferedReader reader=new BufferedReader(new FileReader("D:/code.java"));        String data=null;        //读取一行数据,然后发送出去。readLine()方法阻塞。        while((data=reader.readLine())!=null){            packet=new DatagramPacket(data.getBytes(), data.getBytes().length,address,9999);            socket.send(packet);        }        //关闭资源        socket.close();        reader.close();    }

接收代码:

    static void udpReceiveFile()throws Exception{        //创建一个字符缓冲写入流        BufferedWriter writer=new BufferedWriter(new FileWriter("F:/teset.java"));        //创建DatagramSocket对象,9999是监听的端口        DatagramSocket socket=new DatagramSocket(9999);        socket.setSoTimeout(4000);//设置超时为4秒,若4秒中没有数据,报超时异常,退出程序        while(true){            byte[] datas=new byte[1024];            DatagramPacket packet=new DatagramPacket(datas, datas.length);            //阻塞式方法。所以可以使用while循环            socket.receive(packet);            String string=new String(packet.getData(),0,packet.getLength());            System.out.println(string);            //每读到一行数据,就写入文件,并且再写入一个换行,刷新。            writer.write(string);            writer.newLine();            writer.flush();        }    }

6. TCP的发送和接收

TCP分为客户端和服务端。客户端和 服务端的对象也不尽相同。

  • 客户端只有一个Socket,用来发送和接收消息。客户端的Socket在创建的时候可以指定服务端的端口和IP地址。
  • 服务端有一个ServerSocket,其accept()方法用来等待客户端连接。ServerSocket创建的时候必须指明监听的端口。
    这个Socket对象的使用和客户端的Socket是相同的。其中accept()方法是阻塞式的,只有有客户端连接,才能获取客户端的Socket。一个服务端可以有多个客户端去连接。每连接一个客户端,就创建一个Socket对象
  • Socket可以获取InputSream用来读取数据,获取OutputStream用来向Socket发送数据

实现客户端向服务端发送一条消息,服务端收到消息后,向该客户端反馈一条消息。

客户端代码:

    static void tcpClient()throws Exception{        //创建输入和输出流        InputStream inputStream=null;        OutputStream outputStream=null;        //创建Socket,客户端需要指明服务端(目的)的IP地址和端口号        Socket socket=new Socket("127.0.0.1",10001);        //得到输出流        outputStream=socket.getOutputStream();        //向socket写入数据并且发送        outputStream.write("我是TCP客户端,正在向服务端发消息".getBytes());        //接收服务端发过来的消息        inputStream=socket.getInputStream();        byte[] datas=new byte[1024];        //读取消息        int len=inputStream.read(datas);        System.out.println("客户端收到消息--"+new String(datas,0,len));        //关闭资源        socket.close();    }

服务端代码:

   static void tcpServer()throws Exception{       InputStream inputStream=null;       OutputStream outputStream=null;       //创建ServerSocket对象,必须指明监听的端口       ServerSocket serverSocket=new ServerSocket(10001);       //该方法是阻塞式方法,每有一个客户端连接,就与之建立一个对应的Socket对象。       Socket socket=serverSocket.accept();       //接收客户端发过来的数据       inputStream=socket.getInputStream();       byte []datas=new byte[1024];       int len=inputStream.read(datas);       System.out.println("服务端收到消息--"+new String(datas,0,len));       //向客户端发送数据       outputStream=socket.getOutputStream();       outputStream.write("客户端,你好啊".getBytes());       //关闭资源       socket.close();       //现实中,serverSocket是不能关闭的,因为要一直等待其他客户端的连接       serverSocket.close();   }

6.1 TCP发送和接收图片

发送代码:

    static void tcpSendPicture() throws Exception{        //创建字节缓冲读出流        BufferedInputStream inputStream=new BufferedInputStream(new FileInputStream("D:/view.jpg"));        //创建Socket,客户端需要指明服务端(目的)的IP地址和端口号        Socket socket=new Socket("127.0.0.1",10001);        //将socket的输出输出流转换为缓冲输出流。        BufferedOutputStream outputStream=new BufferedOutputStream(socket.getOutputStream());        int datas=0;        //注意,datas是读到的数据,而不是数据长度。从文件读到数据缓冲区满了以后,使用outputStream发给服务端        while((datas=inputStream.read())!=-1){            outputStream.write(datas);        }        //通知服务端发送完毕,服务端收到此消息会停止继续接收数据。        socket.shutdownOutput();        //关闭资源。        socket.close();        inputStream.close();    }

服务端接收代码:

   static void tcpReceivePicture() throws Exception{       //创建ServerSocket ,绑定监听端口       ServerSocket serverSocket=new ServerSocket(10001);       Socket socket=serverSocket.accept();       //将socket的输入流转换为缓冲输入流,方便读写。       BufferedInputStream inputStream=new BufferedInputStream(socket.getInputStream());       //创建接收数据的IO流对象       BufferedOutputStream outputStream=new BufferedOutputStream(new FileOutputStream("F:/view_copu.jpg"));       //datas是读到的数据,不是数据长度。       int datas=0;       while((datas=inputStream.read())!=-1){           outputStream.write(datas);       }       //关闭资源       serverSocket.close();       serverSocket.close();       outputStream.close();   }

7. URLConnection

代码:

   static void URLtest() throws Exception{    URL url =new URL("https://www.baidu.com/");    URLConnection urlConnection=url.openConnection();    InputStream inputStream=urlConnection.getInputStream();    byte[] datas=new byte[1024];    int len=0;    while((len=inputStream.read(datas))!=-1){        System.out.println(new String(datas,0,len));    }   }
0 0
原创粉丝点击