Java Socket应用

知道网络编程很重要,但是今天才去学习,要学习的东西很多,多积累!

网络基础知识

  • InetAddress类
  • URL
  • TCP编程
  • UDP编程

网络基础

Java对网络编程提供了强大的通信

两台计算机通过网络进行通信

  • IP地址:在网络中唯一标识
  • 协议:能互相理解
  • 端口:标识应用

TCP/IP协议

  • 应用最为广泛的协议
  • 是以TCP和IP为基础的不同层次上多个协议的集合
  • 也称TCP/IP协议族 或 TCP/IP协议栈
  • TCP:Transmission Control Protocol 传输控制协议
  • IP:Internet Protocol 互联网协议
  • 模型
    • 应用层:HTTP FTP SMTP(简单邮件传送协议) Telnet(远程登录服务)
    • 传输层:TCP/IP
    • 网络层
    • 数据链路层
    • 物理层:网线 网卡等

IP地址

为现实网络中不同计算机之间的通信,每台机器都必须有一个唯一的标识

IP地址格式
    IPv4  IPv6

端口

  • 用于区分不同应用程序
  • 端口号范围为0~65535牟其中0~1023位系统所保留
  • IP地址和端口号组成了所谓的Socket,Socket是网络上运行的程序之间双向通信链路的终结点,是TCP和UDP的基础
  • http:80 ftp:21 telnet:23
  • Java中的网络支持
    • InetAddress:用于标识网络上的硬件资源
    • URL:统一资源定位符 用过URL可以直接读取或写入网络上的数据
    • Sockets:使用TCP协议实现网络通信的Sockets相关的类
    • Datagram:使用UDP协议,将数据保存在数据报中,通过网络进行通信

InetAddress类

用于网络上的硬件资源,表示互联网协议(IP)地址
public static void main(String[] args) throws UnknownHostException {
    InetAddress address = InetAddress.getLocalHost();// static instance
    System.out.println(address.getHostName());// 主机名
    System.out.println(address.getHostAddress());// IP地址

    byte[] bytes = address.getAddress();// IP地址的byte数组格式
    System.out.println(Arrays.toString(bytes));

    System.out.println(address);


    InetAddress byName = InetAddress.getByName("runhwguo-PC1"); // 根据主机名
    System.out.println(byName.getHostAddress());

    InetAddress byName1 = InetAddress.getByName("10.6.67.39");// 根据IP地址
    System.out.println(byName1.getHostName());
}

URL

  • Uniform Resource Locator 统一资源定位符,表示Internet上某一资源的地址
  • URL由两部分组成:协议名称和资源名称,中间用冒号隔开
  • 在java.net包中,提供了URL类来表示URL

    URL imooc = new URL(“http://www.imooc.com“);
    // ?后面表示参数,#后面表示锚点
    URL url = new URL(imooc, “/index.html?username=tom#test”);
    System.out.println(url.getProtocol());// http
    System.out.println(url.getHost());// www.imooc.com
    // 如果未指定端口号,则使用默认的端口号,此时getPort()方法返回值为-1
    System.out.println(url.getPort());
    System.out.println(url.getPath());// /index.html
    System.out.println(url.getFile()); // /index.html?username=tom
    System.out.println(url.getRef());// test
    System.out.println(url.getQuery());// username=tom

    用URL读取网页内容
    URL url = new URL("http://www.baidu.com");
    InputStream inputStream = url.openStream();
    
    InputStreamReader streamReader = new InputStreamReader(inputStream,"UTF-8");
    BufferedReader br = new BufferedReader(streamReader); // 用buffer加快速度
    String data = null;
    do {
            data = br.readLine();
            System.out.println(data);
    } while (data != null);
    br.close();
    streamReader.close();
    inputStream.close();
    

Socket通信

TCP协议是面向连接、可靠的、有序的,以字节流的方式发送数据
基于TCP协议实现网络通信的类
  • 客户端的Socket类
  • 服务端的ServerSocket类
Socket通信模型
![通信模型](https://img-blog.csdn.net/20160501173738648)
Socket通信实现步骤
  • 创建ServerSocket和Socket
  • 打开连接到Socket的输入/输出流
  • 按照协议对Socket进行读/写操作
  • 关闭输入输出流、关闭Socket

    Server.java
        public static void main(String[] args) throws IOException {
            ServerSocket serverSocket = new ServerSocket(8888); // port
            System.out.println("server即将启动");
            Socket socket = null;
            int count = 0;
    
        while (true) {
            socket = serverSocket.accept(); // 此时处于阻塞状态,等待客户端请求
            ServerThread serverThread = new ServerThread(socket);
    
            serverThread.start();
            count++;
            System.out.println(count);
        }
    }
    Client.java 
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost",8888);
        OutputStream os = socket.getOutputStream();
        PrintWriter pw = new PrintWriter(os);
        pw.write("tom 123");
        pw.flush();
        socket.shutdownOutput();
    
        InputStream inputStream = socket.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String info;
        while ((info = bufferedReader.readLine()) != null) {
            System.out.println(info);
        }
        bufferedReader.close();
        inputStream.close();
    
        pw.close();
        os.close();
        socket.close();
    }
    
    ServerThread.java // 多线程
    public class ServerThread extends Thread {
        private Socket socket;
    
        public ServerThread(Socket socket) {
            this.socket = socket;
        }
    
        @Override
        public void run() {
            try {
                InputStream inputStream = socket.getInputStream();
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                String info;
                while ((info = bufferedReader.readLine()) != null) {
                    System.out.println(info);
                }
                socket.shutdownInput(); // 先关闭socket
    
                OutputStream outputStream = socket.getOutputStream();
                PrintWriter pw = new PrintWriter(outputStream);
                pw.write("欢迎您!");
                pw.flush();
               // pw.close();
                outputStream.close();
    
                bufferedReader.close();
                inputStreamReader.close();
                inputStream.close();
                socket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
UDP编程
  • UDP协议(用户数据报协议)是无连接、不可靠的、无序的,速度相对比较快,以数据报为载体
  • 进行数据传输时,首先需要将要传输的数据定义成数据报(Datagram),在数据报中指明数据报要达到的Socket(主机地址和端口号),然后再将数据报发送出去
  • 相关操作类
    • DatagramPacket:数据报类
    • DatagramSocket:进行端到端通信的类
  • 服务器端实现步骤
    • 创建DatagramSocket,指定端口号
    • 创建DatagramPacket
    • 接受客户端发送的数据信息
    • 读取数据
  • 客户端实现步骤

    • 定义发送信息
    • 创建DatagramPacket,包含将要发送的信息
    • 创建DatagramSocket
    • 发送数据

      UdpServerThread.java // 多线程
      public class UdpServerThread extends Thread {
          private DatagramSocket socket;
          private DatagramPacket packet;
      
          public UdpServerThread(DatagramSocket socket, DatagramPacket packet) {
              this.socket = socket;
              this.packet = packet;
          }
      
          @Override
          public void run() {
              try {
                  String info = new String(packet.getData(), 0, packet.getLength());
                  System.out.println(info);
      
                  InetAddress address = packet.getAddress();
                  int port = packet.getPort();
                  byte[] data2 = "welcome".getBytes();
                  DatagramPacket packet1 = new DatagramPacket(data2, data2.length, address, port);
      
                  socket.send(packet1);
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
      
      UdpServer.java
          public static void main(String[] args) throws IOException {
              DatagramSocket socket = new DatagramSocket(8888);
      
              System.out.println("server start");
              int count = 0;
              while (true) {
                  byte[] datas = new byte[1024];
      
                  DatagramPacket packet = new DatagramPacket(datas, datas.length);
                  socket.receive(packet); // 此时处于阻塞状态,等待客户端请求
                  UdpServerThread udpServerThread = new UdpServerThread(socket,packet);
                  udpServerThread.setPriority(4);// 未设置优先级可能会导致运行时速度非常慢,可降低优先级
                  udpServerThread.start();
                  count++;
                  System.out.println(count);
              }
          }
      
      UdpClient.java
          public static void main(String[] args) throws IOException {
              InetAddress address = InetAddress.getByName("localhost");
              int port = 8888;
              byte[] data = "用户名:guo;密码:123".getBytes();
              DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
      
      
              DatagramSocket socket = new DatagramSocket();
      
              socket.send(packet);
      
      
              byte[] data2 = new byte[1024];
              DatagramPacket packet2 = new DatagramPacket(data2, data2.length);
              socket.receive(packet2);
              String reply = new String(data2, 0, packet.getLength());
              System.out.println(reply);
      
              socket.close();
          }
      

Socket总结

  • 多线程的优先级
  • 关闭流问题与socket关闭问题
  • 传递对象
  • 传递文件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值