socket编程(Java)

文章目录

IP

IP地址的API:java.net.InetAddress

IP地址分类:

  • IPV4 / IPV6

    • IPV4:如:127.0.0.1。4个字节(32bit)。42亿多(2^32)。30亿在北美,亚洲4亿。2011年用尽。

    • IPV6:如:fe80::5594:3b26:bd74:92dc%19。16个字节(128bit,8个无符号整数)。

  • 公网 / 私网

    • ABCD类地址

测试InetAddress

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

public class TestInetAddress {
    public static void main(String[] args) {
        try {
            // 获取本机的IP
            InetAddress ip1 = InetAddress.getByName("127.0.0.1");
            System.out.println(ip1); // /127.0.0.1
            InetAddress ip2 = InetAddress.getByName("localhost");
            System.out.println(ip2); // localhost/127.0.0.1
            InetAddress localHost = InetAddress.getLocalHost();
            System.out.println(localHost); // Legion-Y7000P-2019-PG0/10.16.95.130

            // 获取网站的ip
            InetAddress ip3 = InetAddress.getByName("www.jd.com");
            System.out.println(ip3); // www.jd.com/183.66.105.73

            System.out.println(ip3.getAddress()); // [B@1b6d3586
            System.out.println(ip3.getCanonicalHostName()); // 219.151.17.75

            System.out.println(ip3.getHostAddress()); // 219.151.17.75
            System.out.println(ip3.getHostName()); // www.jd.com
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

PORT

ip地址:代表服务器的具体地址
端口号:代表服务器中所提供的服务
ip+port:哪台服务器的哪个服务

端口号范围:0-65535

TCP、UDP:不同协议可以用相同的端口,不会冲突。单个协议下端口号不能冲突。

端口号分类:
公有端口:0-1023(如:http的80,https的443,ftp的21,telnet的23)
程序注册端口:1024-49151(如tomcat的80,mysql的3306,oracle的1521,redis的6379,rabbitmq的5672,15672)
动态端口、私有端口:49152-65535

windows:
	netstat -ano:查看所有端口
	netstat -ano|findstr "5900":查看指定的端口
	tasklist|findstr "5500":查看指定端口的进程
	ctrl + shift + esc:打开任务管理器
import java.net.InetSocketAddress;

public class TestInetSocketAddress {
    public static void main(String[] args) {
        InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 8080);
        System.out.println(inetSocketAddress); // /127.0.0.1:8080
        InetSocketAddress inetSocketAddress1 = new InetSocketAddress("www.jd.com", 443);
        System.out.println(inetSocketAddress1); // www.jd.com/221.228.219.213:443

        System.out.println(inetSocketAddress1.getAddress()); // www.jd.com/219.151.17.75
        System.out.println(inetSocketAddress1.getHostName()); // www.jd.com
        System.out.println(inetSocketAddress1.getHostString()); // www.jd.com
        System.out.println(inetSocketAddress1.getPort()); // 443
    }
}

协议

TCP

客户端Socket与服务端ServerSocket进行通信

客户端TcpClient:

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class TcpClient {
    public static void main(String[] args) throws IOException {
        Socket socket = null;
        OutputStream os = null;
        try {
            InetAddress address = InetAddress.getByName("127.0.0.1");
            int port = 4444;

            socket = new Socket(address, port);

            os = socket.getOutputStream();
            os.write("客户端发送信息!".getBytes());
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                socket.close();
            }
        }
    }

}

服务端TcpServer

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

public class TcpServer {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;

        try {
            serverSocket = new ServerSocket(4444);

            while (true){
                socket = serverSocket.accept(); // 服务端一直监听
                is = socket.getInputStream();

                baos = new ByteArrayOutputStream();

                byte[] bytes = new byte[1024];
                int len;
                while ((len = is.read(bytes)) != -1){
                    baos.write(bytes, 0, len);
                }
                System.out.println(baos.toString());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

客户端Socket与服务端ServerSocket收发文件

服务端

import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TcpServerGetFile {
    /*
    	服务端通过输入流读取客户端发来的文件
     */
    public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        FileOutputStream fos = null;
        OutputStream os = null;

        serverSocket = new ServerSocket(1234);
        socket = serverSocket.accept();
        is = socket.getInputStream(); // 获得文件流对象

        int len;
        byte[] buffer = new byte[1024];

        fos = new FileOutputStream("test/1.md");

        while ((len = is.read(buffer)) != -1) {
            fos.write(buffer, 0, len);
        }

        // 通知客户端接收完毕
        os = socket.getOutputStream();
        os.write("接受完毕,请客户端断开连接!".getBytes());

        os.close();
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

客户端

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

public class TcpClientSendFile {
    /*
        客户端通过socket获得输出流,输出文件
     */
    public static void main(String[] args) throws Exception {
        Socket socket = null;
        FileInputStream fis = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        OutputStream os = null;

        socket = new Socket(InetAddress.getByName("127.0.0.1"), 1234);

        fis = new FileInputStream(new File("test/socket.md"));
        os = socket.getOutputStream();

        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }

        // 通知服务器传输结束
        socket.shutdownOutput();

        is = socket.getInputStream();
        baos = new ByteArrayOutputStream();

        byte[] buffer2 = new byte[1024];
        int len2;

        while ((len2 = is.read(buffer2)) != -1) {
            baos.write(buffer2, 0, len2);
        }

        System.out.println(baos.toString());

        os.close();
        baos.close();
        is.close();
        fis.close();
        socket.close();
    }
}

UDP

没有客户端和服务端的概念,只有发送端和接收端的概念

UdpSend.java

package udp;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UdpSend {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(5678);

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            String msg = br.readLine();

            DatagramPacket packet = new DatagramPacket(
                    msg.getBytes(),
                    0,
                    msg.getBytes().length,
                    InetAddress.getByName("127.0.0.1"),
                    1234);

            socket.send(packet);
            if ("bye".equals(msg)) {
                break;
            }
        }
        // 关闭资源
        socket.close();
    }
}
UdpRec.java

package udp;

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

public class UdpRec {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(1234);

        byte[] buffer = new byte[1024];
        while (true) {
            DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);

            socket.receive(packet);

//        System.out.println(packet.getAddress().getHostAddress());
            String data = new String(packet.getData(), 0, packet.getLength());
            System.out.println(data);

            if ("bye".equals(data)) {
                break;
            }
        }
        socket.close();
    }
}

实习学生和老师聊天:SendTask.java、RecTask.java、Student.java、Teacher.java
使用多线程调度实现

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class SendTask implements Runnable {
    private int fromPort;
    private int toPort;
    private String toIp;
    private DatagramSocket socket;
    private BufferedReader reader;

    public SendTask(int fromPort, int toPort, String toIp) {
        this.fromPort = fromPort;
        this.toPort = toPort;
        this.toIp = toIp;

        try {
            this.socket = new DatagramSocket(this.fromPort);
            reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while (true) {
            try {
                String msg = reader.readLine();
                DatagramPacket packet = new DatagramPacket(
                        msg.getBytes(),
                        0,
                        msg.getBytes().length,
                        InetAddress.getByName(toIp),
                        toPort);

                socket.send(packet);
                if ("bye".equals(msg)) {
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // 关闭资源
        socket.close();
    }
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class RecTask implements Runnable{

    private int port;
    private DatagramSocket socket;


    public RecTask(int port) {
        this.port = port;

        init();
    }

    private void init() {
        try {
            socket = new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while (true){
            byte[] buffer = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);

            try {
                socket.receive(packet);
                String data = new String(packet.getData(), 0, packet.getLength());
                System.out.println(packet.getAddress().getHostAddress() + "/" + port + ": " + data);

                if ("bye".equals(data)) {
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        socket.close();
    }
}
package udp;

public class Student {
    public static void main(String[] args) {
        new Thread(new SendTask(1111, 2222, "127.0.0.1")).start();
        new Thread(new RecTask(3333)).start();
    }
}
package udp;

public class Teacher {
    public static void main(String[] args) {
        new Thread(new SendTask(4444, 3333, "127.0.0.1")).start();
        new Thread(new RecTask(2222)).start();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值