> 文档中心 > JAVA-网络编程

JAVA-网络编程


网络编程

计算机网络

  • 计算机网络是指将地理位置不同具有独立功能的多台计算机及其外部设备通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议管理和协调下,实现资源共享信息传递的计算机系统。

网络编程要素

  • IP和端口
  • 网络通信协议

IP地址

java.net.InetAddress此类表示Internet协议(IP)地址

概念

  • 唯一定位一台网络上计算机
  • 127.0.0.1 :本机localhost地址
  • IP地址分类
  1. IPV4:4个字节组成
  2. IPV6:128位。8个无符号整数
  3. 公网(互联网)
    JAVA-网络编程
    JAVA-网络编程
  4. 私网(局域网)
  • 域名:为了记忆IP
import java.net.InetAddress;import java.net.UnknownHostException;import java.util.Arrays;public class Test27 {    public static void main(String[] args) throws UnknownHostException { //查询本地地址 InetAddress[] allByName = InetAddress.getAllByName("127.0.0.1"); InetAddress[] allByName1 = InetAddress.getAllByName("localhost"); InetAddress allByName2 = InetAddress.getLocalHost(); System.out.println(Arrays.toString(allByName)); System.out.println(Arrays.toString(allByName1)); System.out.println( allByName2); //查询网站地址 InetAddress[] allByName3 = InetAddress.getAllByName("www.baidu.com"); System.out.println(Arrays.toString(allByName3)); //常用方法 System.out.println(allByName3[0].getHostAddress());//ip System.out.println(allByName3[0].getHostName());//域名//套接字 InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1",8080); System.out.println(inetSocketAddress);    }}

端口

概念

  • 端口表示计算机上的一个程序的进程,不同的进程有不同的端口号,用来区分软件!
  • 规定值时0~65535
  • 单个协议下,端口号不能冲突
  • 端口分类
  1. 公用端口:0~1023
    • HTTP:80
    • HTTPS:443
    • FTP:21
  2. 程序注册端口:1024~49151,分配用户或者程序
    • tomcat:8080
    • mysql:3306
    • oracle:1521
    • pg:5432
  3. 动态、私有:49152~65535
  • 查看所有端口命令netstat -ano
  • 查看指定的端口netstat -ano|findstr "端口号"
  • 查看指定端口的进程tasklist|findstr "端口号"

网络通信协议

JAVA-网络编程
JAVA-网络编程
JAVA-网络编程

  • TCP:用户传输协议
  • IP:用户数据报协议

TCP

TCP

  1. 连接、稳定
  2. 三次握手、四次挥手
  3. 分为客户端和服务端
  4. 传输完成,释放连接,效率低
TCP例子:实现消息传递
package com.utils;import java.io.IOException;import java.io.OutputStream;import java.net.*;import java.nio.charset.StandardCharsets;public class TestClient {    public static void main(String[] args) { Socket socket=null; OutputStream outputStream=null; try {     //需要知道服务器的地址,端口号     //InetAddress serverIp = InetAddress.getByName("172.0.0.1");     //int port=9999;     //创建socket连接     //socket= new Socket(serverIp,port);     socket=new Socket();     InetSocketAddress address = new InetSocketAddress("127.0.0.1", 9999);     socket.connect(address,60000);     //     //发送消息     outputStream= socket.getOutputStream();     outputStream.write("陈行恩".getBytes()); } catch (IOException e) {     e.printStackTrace(); } finally {     try {  if (outputStream != null) {      outputStream.close();  }  if (socket != null) {      socket.close();  }     }     catch (IOException e) {      e.printStackTrace();  }     } }    }
package com.utils;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.InetSocketAddress;import java.net.ServerSocket;import java.net.Socket;import java.nio.charset.StandardCharsets;public class TestService {    public static void main(String[] args) { ServerSocket serverSocket=null; Socket accept=null; InputStream inputStream=null; ByteArrayOutputStream byteArrayOutputStream=null; try {     //自己需要有一个IP地址     serverSocket= new ServerSocket(9999);     //等待客户端连接     accept= serverSocket.accept();     //读取客户端信息     inputStream = accept.getInputStream();     //管道流     byteArrayOutputStream = new ByteArrayOutputStream();     byte[] bytes = new byte[1024];     int len;     while ((len=inputStream.read(bytes))!=-1){  byteArrayOutputStream.write(bytes,0,len);     }     System.out.println(byteArrayOutputStream.toString()); } catch (IOException e) {     e.printStackTrace(); }finally {     try {  if (byteArrayOutputStream!=null){      byteArrayOutputStream.close();  }  if (inputStream!=null){      inputStream.close();  }  if (accept!=null){      accept.close();  }  if (serverSocket!=null){      serverSocket.close();  }     } catch (IOException e) {  e.printStackTrace();     } }    }}

先启动服务端,再启动客户端

TCP例子:实现文件传递
package com.utils;import java.io.*;import java.net.ServerSocket;import java.net.Socket;public class TestService2 {    public static void main(String[] args) { ServerSocket serverSocket=null; Socket accept=null; InputStream inputStream=null; FileOutputStream fileOutputStream=null; OutputStream outputStream=null; try {     //创建服务     serverSocket = new ServerSocket(9999);     //服务已经创建     System.out.println("已经创建了");     //监听连接状态     accept = serverSocket.accept();     //获取输入流     inputStream = accept.getInputStream();     //文件输出流     fileOutputStream = new FileOutputStream(new File("C:\\Users\\admin\\Pictures\\cx1.png"));     byte[] bytes = new byte[1024];     int len;     while ((len=inputStream.read(bytes))!=-1){  fileOutputStream.write(bytes,0,len);     }     //通知客户端我已接受     outputStream = accept.getOutputStream();     outputStream.write("OK".getBytes()); } catch (IOException e) {     e.printStackTrace(); } finally {  try{      if (fileOutputStream!=null) {   fileOutputStream.close();      }      if (inputStream!=null) {   inputStream.close();      }      if (accept!=null) {   accept.close();      }      if (serverSocket!=null) {   serverSocket.close();      }  } catch (IOException e) {      e.printStackTrace();  }     } }    }
package com.utils;import java.io.*;import java.net.InetSocketAddress;import java.net.Socket;public class TestClient2 {    public static void main(String[] args) { Socket socket=null; OutputStream outputStream=null; FileInputStream file=null; InputStream inputStream=null; ByteArrayOutputStream byteArrayOutputStream=null; try {     //创建Socket连接     socket=new Socket();     InetSocketAddress address = new InetSocketAddress("127.0.0.1", 9999);     socket.connect(address,60000);     //创建一个输出流     outputStream = socket.getOutputStream();     //读取文件     file = new FileInputStream(new File("C:\\Users\\admin\\Pictures\\cx\\java.png"));     //将文件写入流中     byte[] bytes = new byte[1024];     int len;     while ((len= file.read(bytes))!=-1){  outputStream.write(bytes,0,len);     }     //通知服务器已经传输完成了     socket.shutdownOutput();     //确定服务器接受,客户端就断开连接     inputStream = socket.getInputStream();     byteArrayOutputStream = new ByteArrayOutputStream();     byte[] bytes2=new byte[1024];     int len2;     while ((len2=inputStream.read(bytes2))!=-1){  byteArrayOutputStream.write(bytes2,0,len2);     }     System.out.println(byteArrayOutputStream.toString()); } catch (Exception e) {     e.printStackTrace(); } finally {  try {      if (byteArrayOutputStream != null) {   byteArrayOutputStream.close();      }      if (inputStream != null) {   inputStream.close();      }      if (file != null) {   file.close();      }      if (outputStream != null) {   outputStream.close();      }      if (socket != null) {   socket.close();      }  }catch(IOException e) {      e.printStackTrace();  }     } }    }

UDP

java.net.DatagramPacket该类表示数据报包
java.net.DatagramSocket该类表示用于发送和接受数据报数据包的套接字

  • UDP
  1. 不连接、不稳定
  2. 客户端与服务端没有明显的界限
UDP例子:数据报的发送与接收
package com.utils;import java.io.IOException;import java.net.*;public class TestUdpClient {    public static void main(String[] args) throws IOException { //1.建立socket DatagramSocket datagramSocket = new DatagramSocket(); //2.获取目标地址 InetAddress ip = InetAddress.getByName("127.0.0.1"); int port=8989; //3.准备发送的信息 String msg="cx"; //4.建立发送包 DatagramPacket datagramPacket = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, ip, port); //5.将包发送出去 datagramSocket.send(datagramPacket); //6.关闭流 datagramSocket.close();    }}
package com.utils;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;public class TestUdpClient2 {    public static void main(String[] args) throws IOException { //开放端口,开放后,一直处于监听状态 DatagramSocket datagramSocket = new DatagramSocket(8989); //接收包 byte[] bytes = new byte[1024]; DatagramPacket datagramPacket = new DatagramPacket(bytes,0,bytes.length); datagramSocket.receive(datagramPacket);//阻塞接受 System.out.println(datagramPacket.getAddress().getHostAddress()); System.out.println(new String(datagramPacket.getData(),0,datagramPacket.getLength())); //关闭连接 datagramSocket.close();    }}
UDP例子:数据报的循环发送与接收
package com.utils;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;public class TestUdpReceiver {    public static void main(String[] args) throws IOException { DatagramSocket datagramSocket = new DatagramSocket(9999); while (true){     //准备接收报的容器     byte[] bytes = new byte[1024];     DatagramPacket datagramPacket = new DatagramPacket(bytes,0,bytes.length);     //接收报的数据放入容器中     datagramSocket.receive(datagramPacket);     //将数据转为String     byte[] data = datagramPacket.getData();     //byte[]转String后,去掉String后面的空字符     String s = new String(data, 0, data.length).trim();     System.out.println(s);     //如果接收报额数据是no,就表示传输完成     if(s.equals("no")){  break;     } } //关闭 datagramSocket.close();    }}
package com.utils;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetSocketAddress;public class TestUdpSender {    public static void main(String[] args) throws IOException { //建立socket DatagramSocket datagramSocket = new DatagramSocket(9898); //准备数据 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); while (true){     String data = bufferedReader.readLine();//读取一行     byte[] bytes = data.getBytes();     //建立数据报     DatagramPacket datagramPacket = new DatagramPacket(bytes,0, bytes.length, new InetSocketAddress("127.0.0.1", 9999));     //发送数据报     datagramSocket.send(datagramPacket);     //如果输入的是no,那么发送端也关闭     if (data.equals("no")){  break;     } } //关闭 datagramSocket.close();    }}
UDP例子:多线程聊天
package com.utils;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetSocketAddress;public class TestSenderThreadUdp implements Runnable{    private int localPort;    private String hostName;    private int toPort;    private String username;    private DatagramSocket datagramSocket=null;    private BufferedReader bufferedReader=null;    public TestSenderThreadUdp(String username,int localPort,String hostName,int toPort) { this.localPort=localPort; this.hostName=hostName; this.toPort=toPort; this.username=username;    }    @Override    public void run() { try {     //建立socket     datagramSocket = new DatagramSocket(localPort);     //准备数据     bufferedReader = new BufferedReader(new InputStreamReader(System.in));     while (true){  String data = bufferedReader.readLine();//读取一行  byte[] bytes = (this.username+":"+data).getBytes();  //建立数据报  DatagramPacket datagramPacket = new DatagramPacket(bytes,0, bytes.length, new InetSocketAddress(hostName, toPort));  //发送数据报  datagramSocket.send(datagramPacket);  //如果输入的是no,那么发送端也关闭  if (data.equals("no")){      break;  }     } } catch (IOException e) {     e.printStackTrace(); } finally {     //关闭     datagramSocket.close(); }    }}
package com.utils;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;public class TestReceiverThreadUdp implements Runnable{    private DatagramSocket datagramSocket=null;    private int localPort;    public TestReceiverThreadUdp(int localPort) { this.localPort=localPort;    }    @Override    public void run() { try {     datagramSocket = new DatagramSocket(localPort);     while (true){  //准备接收报的容器  byte[] bytes = new byte[1024];  DatagramPacket datagramPacket = new DatagramPacket(bytes,0,bytes.length);  //接收报的数据放入容器中  datagramSocket.receive(datagramPacket);  //将数据转为String  byte[] data = datagramPacket.getData();  //byte[]转String后,去掉String后面的空字符  String s = new String(data, 0, data.length).trim();  System.out.println(s);  //如果接收报额数据是no,就表示传输完成  if(s.equals("no")){      break;  }     } } catch (IOException e) {     e.printStackTrace(); } finally {     //关闭     datagramSocket.close(); }    }}
package com.utils;public class TestUser1Udp {    public static void main(String[] args) { new Thread(new TestReceiverThreadUdp(8999)).start(); new Thread(new TestSenderThreadUdp("cx",8989,"127.0.0.1",9991)).start();    }}
package com.utils;public class TestUser2Udp {    public static void main(String[] args) { new Thread(new TestReceiverThreadUdp(9991)).start(); new Thread(new TestSenderThreadUdp("cx1",9999,"127.0.0.1",8999)).start();    }}

URL

统一资源定位符:定位资源的,定位互联网上的某一个资源
协议://ip地址:端口号/项目名/资源

package com.utils;import java.net.MalformedURLException;import java.net.URL;public class TestUrl {    public static void main(String[] args) throws MalformedURLException { URL url = new URL("http://localhost:8080/cx/index.html?username=cx&age=12"); System.out.println(url.getProtocol());//获取协议 System.out.println(url.getHost());//主机ip System.out.println(url.getPort());//端口 System.out.println(url.getPath());//文件 System.out.println(url.getFile());//获取全路径 System.out.println(url.getQuery());//参数    }}
URL例子:下载网上内容
package com.utils;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.MalformedURLException;import java.net.URL;import java.net.URLConnection;public class TestUrl {    public static void main(String[] args) throws IOException { //1.下载地址 URL url = new URL("https://t10.baidu.com/it/u=4127376780,661767277&fm=58");//2.连接到这个工资 HTTP URLConnection urlConnection = url.openConnection(); InputStream inputStream = urlConnection.getInputStream(); FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\admin\\Pictures\\cx\\c.png"); byte[] bytes = new byte[1024]; int len; while ((len=inputStream.read(bytes))!=-1){     fileOutputStream.write(bytes,0,len); }    }}

=========================================================
javase总结 推荐狂神说

三国人物百科