Java 网络编程

一开始学 Java 网络编程的时候,因为不懂 TCP/IP 协议,被搞得一头雾水。前段时间读了《计算机网络》,对 TCP/IP 协议有了新的认识,现在再来写一下。

阅读前可参考博文:

本来也想总结一下 TCP 的知识点,但是 TCP 真的是太复杂了,三言两语是解释不清楚的。如果以后有机会深入了解 TCP,再尝试着总结一下。

关于 TCP 与 UDP 相关的内容就不再介绍了,会在注释里作一些相关解释。

一、UDP(User Datagram Protocol)编程

数据接收端(当发送端发送的消息是“over”时,关闭通信)

public class UdpRecieve {
    public static void main(String[] args) throws IOException {
        /**
         * DatagramSocket:UDP 协议 API
         * 6457:一个16位的协议端口号,因此最大值为65535,用于实现不同主机进程之间的逻辑通信
         * 注意:这个端口号是主机之间用于进程识别的端口号,不是数据发送的端口号
         */
        DatagramSocket socket = new DatagramSocket(6457);
        
        while (true) {
		    /**
	        * 注意接收的字节数组大小,一般一个中文汉字占2个字节
	        */
            byte[] bytes = new byte[1024];
            DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
            /**
             * 接收发送端发送的数据
             * 并将收到的数据(发送端的IP地址,端口,数据等)封装成数据报
             */
            socket.receive(packet);
            /**
             * 获取数据报中的数据信息,主机IP,端口号等
             * 关于数据报中有哪些信息,可以参照UDP报文段格式(包括首部与数据信息)
             */
            InetAddress host = packet.getAddress();
            int port = packet.getPort();
            String message = new String(packet.getData(), 0, packet.getLength());

            System.out.println(host + "发来了消息,使用的端口号是:" 
                    + port + ",数据内容:" +message);
            if("over".equals(message)) {
                socket.close();
                break;
            }
        }
    }
}

数据发送端(从控制台接收用户输入的数据,如果输入“over”停止发送):

public class UdpSend {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        /**
         * 指定数据接收端的IP地址,用于找到目的主机
         * 指定数据接收端的端口号,用于找到目的主机中的具体进程
         */ 
        String host = "172.18.126.14";
        int port = 6457;
        String line = null;

        while((line = reader.readLine()) != null) {
            byte[] bytes = line.getBytes();
            DatagramSocket socket = new DatagramSocket();
            /**
             * 在数据报中封装接收端的IP地址,端口号与发送的数据
             */
            DatagramPacket packet = new DatagramPacket(bytes, bytes.length
                    , InetAddress.getByName(host), port);
            socket.send(packet);
            
            if("over".equals(line)) {
                socket.close();
                break;
            }
        }

        reader.close();
    }
}

程序运行的时候,先运行数据接收端,然后再运行数据发送端。如果数据发送端先运行会因为找不到目的主机的进程,而丢弃数据。

二、TCP(Transmission Controll Protocol)编程

服务端(接收客户端信息并回应):

public class TcpServer {
    public static void main(String[] args) throws IOException {
        /**
         * ServerSocket:TCP 服务端 API
         * 指定服务端使用的端口号
         */
        ServerSocket serverSocket = new ServerSocket(7854);
        /**
         * 创建套接字对象,套接字是TCP连接的端点
         * TCP套接字=IP地址:端口号
         * 因为UDP是面向无连接的,因此在UDP中不存在套接字的概念
         */
        Socket socket = serverSocket.accept();

        /**
         * 根据套接字获取数据发送方的IP地址与使用的端口号
         */
        InetAddress host = socket.getInetAddress();
        int port = socket.getPort();
        /**
         * 根据套接字对象获取数据输入流对象
         */
        InputStream in = socket.getInputStream();
        byte[] bytes = new byte[1024];
        /**
         * 从数据输入流中读取发送的数据
         */
        int len = in.read(bytes);
        String message = new String(bytes, 0, len);
        System.out.println(host + "发来了消息,使用的端口号是:"
                + port + ",数据内容:" +message);

        /**
         * 因为TCP提供全双工的数据通信,在确认消息收到后
         * 返回一个确认消息给发送端
         */
        OutputStream out = socket.getOutputStream();
        out.write("数据已收到".getBytes());
        
        serverSocket.close();
        socket.close();
        in.close();
        out.close();
    }
}

客户端(发送消息,并接收服务端的确认消息):

public class TcpClient {
    public static void main(String[] args) throws IOException {
        /**
         * 创建客户端套接字,指定服务端主机IP地址与端口号
         */
        Socket socket = new Socket( "172.18.126.14", 7854);
        /**
         * 根据套接字对象获取输出流对象,并将数据发送
         */
        OutputStream out = socket.getOutputStream();
        out.write("嘿嘿嘿~我来了".getBytes());

        /**
         * 用于接收服务端发出的消息确认
         */
        byte[] bytes = new byte[1024];
        InputStream in = socket.getInputStream();
        int len = in.read(bytes);
        String responseMessage = new String(bytes, 0, len);
        System.out.println("客户端收到了确认:" + responseMessage);
        
        socket.close();
        out.close();
        in.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值