Socket

网络编程

查询ip

import java.net.InetAddress;
import java.net.UnknownHostException;

public class MyInetAddress {
    public static void main(String[] args) {
        try {
            // 查询本机地址
            InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1"); // /127.0.0.1
            System.out.println(inetAddress1);
            InetAddress inetAddress2 = InetAddress.getByName("localhost"); // localhost/127.0.0.1
            System.out.println(inetAddress2);
            InetAddress inetAddress3 = InetAddress.getLocalHost(); // JSSM-20210706VO/192.168.40.167
            System.out.println(inetAddress3);

            // 查询网站ip地址
            InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com"); // www.baidu.com/180.101.49.11
            System.out.println(inetAddress4);

            // 常用方法
            System.out.println(inetAddress4.getAddress()); // [B@4783da3f
            System.out.println(inetAddress4.getCanonicalHostName()); // 180.101.49.11
            System.out.println(inetAddress4.getHostAddress()); // 180.101.49.11
            System.out.println(inetAddress4.getHostName()); // www.baidu.com
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

查询端口

  • 不同进程有不同的端口号,用来区分软件

  • 0~65535

  • TCP、UDP:65535*2。单个协议下端口号不能冲突

  • 公有端口:1~1023

    • HTTP:80
    • HTTPS:443
    • FTP:21
    • Telent:23
  • 程序注册端口:1024~49151

    • Tomcat:8080
    • MySQL:3306
    • Oracle:1521
  • 动态、私有端口:49151~65535

    • netstat -ano:查看所有端口
import java.net.InetSocketAddress;

public class MySocketAddress {
    public static void main(String[] args) {
        InetSocketAddress inetSocketAddress1 = new InetSocketAddress("127.0.0.1", 8080);
        InetSocketAddress inetSocketAddress2 = new InetSocketAddress("localhost", 8080);

        System.out.println(inetSocketAddress1); // /127.0.0.1:8080
        System.out.println(inetSocketAddress2); // localhost/127.0.0.1:8080

        System.out.println(inetSocketAddress1.getAddress()); // /127.0.0.1
        System.out.println(inetSocketAddress1.getHostName()); // 127.0.0.1
        System.out.println(inetSocketAddress1.getPort()); // 8080
    }
}

TCP

普通版

  • MyServer.java
package demo;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServer {

    public static void main(String[] args) {
        ServerSocket serverSocket = null; // 新建ServerSocket对象
        Socket socket = null; // 接收客户端连接
        InputStream is = null; // 用于读取客户端消息
        OutputStream os = null;
        ByteArrayOutputStream baos = null;

        try {
            // 1.创建指定端口的连接
            serverSocket = new ServerSocket(9999);

            while (true){
                // 2.监听 没有连接就阻塞在此
                socket = serverSocket.accept();

                // 3.从socket取出来自客户端的数据
                is = socket.getInputStream();
                // 解析数据
                // 方法一
/*                baos = new ByteArrayOutputStream();
                byte[] buff = new byte[1024];
                int len;
                while ((len=is.read(buff))!=-1){
                    baos.write(buff,0,len);
                }
                System.out.println(baos);*/

                // 方法二
                InputStreamReader reader = new InputStreamReader(is);
                BufferedReader bufReader = new BufferedReader(reader);
                String s;
                StringBuffer sb = new StringBuffer();
                while ((s = bufReader.readLine()) != null) {
                    sb.append(s);
                }
                System.out.println("服务器:" + sb);
                // 关闭输入流
                socket.shutdownInput();

                // 4.向socket写入数据,发送给客户端
                os = socket.getOutputStream();
                os.write(("服务端返回给客户端的信息").getBytes());
                os.flush(); // 强制将缓冲区中的数据发送出去,不必等到缓冲区满
                // 关闭输出流
                socket.shutdownOutput();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            /**
             * 在使用TCP编程的时候,最后需要释放资源,关闭socket(socket.close());
             * 关闭socket输入输出流(socket.shutdownInput()以及socket.shutdownOutput());关闭IO流(is.close() os.close())。
             * 需要注意的是:关闭socket的输入输出流需要放在关闭Io流之前。
             * 因为关闭IO流会同时关闭socket,一旦关闭了socket的,就不能再进行socket的相关操作了。
             * 而只关闭socket输入输出流(socket.shutdownInput()以及socket.shutdownOutput())不会完全关闭socket,此时任然可以进行socket方面的操作。
             * 所以要先调用socket.shutdownXXX,然后再调用io.close();
             */
            if(baos != null){
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(is != null){
                try {
                    is.close(); // 关闭IO流会同时关闭socket
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (os != null) {
                try {
                    socket.shutdownOutput();
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(socket != null){
                try {
                    // 关闭socket
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(serverSocket != null){
                try {
                    // 关闭serverSocket
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • MyClient.java
package demo;

import java.io.*;
import java.net.Socket;

public class MyClient {

    public static void main(String[] args) {
        Socket socket = null;
        OutputStream os = null;

        try {
            // 1.创建socket连接
            socket = new Socket("127.0.0.1", 9999);

            // 2.向socket写入数据,发送给服务端
            // 2.1发送文字
/*            os = socket.getOutputStream();
            os.write("客户端发送给服务端的信息".getBytes());
            os.flush();
            // 关闭输出流
            socket.shutdownOutput();*/

            // 2.2发送图片
            os = socket.getOutputStream();
            // 读取文件
            FileInputStream fis = new FileInputStream(new File("haha.jpg"));
            // 写出文件到输出流中
            byte[] buffer = new byte[1024];
            int len;
            while ((len=fis.read(buffer))!=-1){
                os.write(buffer,0,len);
            }
            os.flush();
            socket.shutdownOutput();

            // 3.从socket取出来自服务端的数据
            InputStream is = socket.getInputStream();
            // 解析服务器返回的数据
            InputStreamReader reader = new InputStreamReader(is);
            BufferedReader bufReader = new BufferedReader(reader);
            String s;
            final StringBuffer sb = new StringBuffer();
            while ((s = bufReader.readLine()) != null) {
                sb.append(s);
            }
            System.out.println(sb);
            // 关闭输入流
            socket.shutdownInput();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 4.释放所有资源
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

多线程版

  • MyServerThread.java把socket封装在Thread内部
package multipleservice;

import java.io.*;
import java.net.Socket;

public class MyServerThread extends Thread {
    private Socket socket;

    public MyServerThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        super.run();
        InputStream is = null; // 用于读取客户端消息
        OutputStream os = null;
        ByteArrayOutputStream baos = null;

        try {
            // 1.从socket取出来自客户端的数据
            is = socket.getInputStream();
            // 2.解析数据
            // 2.1接受文字
            // 方法一
/*                baos = new ByteArrayOutputStream();
                byte[] buff = new byte[1024];
                int len;
                while ((len=is.read(buff))!=-1){
                    baos.write(buff,0,len);
                }
                System.out.println(baos);*/

            // 方法二
/*            InputStreamReader reader = new InputStreamReader(is);
            BufferedReader bufReader = new BufferedReader(reader);
            String s;
            StringBuffer sb = new StringBuffer();
            while ((s = bufReader.readLine()) != null) {
                sb.append(s);
            }
            System.out.println("服务器:" + sb);
            // 关闭输入流
            socket.shutdownInput();*/

            // 2.2接受图片
            FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
            byte[] buffer = new byte[1024];
            int len;
            while ((len=is.read(buffer)) != -1){
                fos.write(buffer,0,len);
            }
            socket.shutdownInput();

            // 3.向socket写入数据,发送给客户端
            os = socket.getOutputStream();
            os.write(("服务端返回给客户端的信息").getBytes());
            os.flush();
            // 关闭输出流
            socket.shutdownOutput();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 释放所有资源
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close(); // 关闭IO流会同时关闭socket
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    // 关闭socket
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

  • MyMultiThreadServer.java
package multipleservice;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class MyMultiThreadServer {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;

        try {
            // 1.新建serverSocket对象并指定端口
            serverSocket = new ServerSocket(9999);

            // 2.不停的监听客户端
            while (true) {
                System.out.println("监听客户端ing");
                // accept方法会阻塞,直到有客户端与之建立连接
                Socket socket = serverSocket.accept();
                // 将socket放到子线程中
                new MyServerThread(socket).start();
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 3.释放资源
            if (serverSocket != null) {
                try {
                    // 关闭serverSocket
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

UDP

package ip;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

//还是要等待客户端的连接
public class UdpServer {
    public static void main(String[] args) throws Exception{

        //开放端口
        DatagramSocket datagramSocket = new DatagramSocket(9090);
        //接收数据包
        byte[] buffer = new byte[1024];
        DatagramPacket datagramPacket = new DatagramPacket(buffer, 0, buffer.length);

        datagramSocket.receive(datagramPacket);//阻塞接收
        System.out.println(datagramPacket.getAddress());
        System.out.println(new String(datagramPacket.getData(), 0, datagramPacket.getLength()));

        datagramSocket.close();
    }
}
posted @ 2021-10-09 00:52  n1ce2cv  阅读(39)  评论(0编辑  收藏  举报