Java基础巩固系列 TCP与UDP编程(网络通信的要素——网络通信协议)

TCP与UDP属于传输层

TCP与UDP:

基于Socket的TCP编程

由上理论可知想要TCP编程必须使用到Socket,客户端(client)使用Socket,服务端(server)使用ServerSocket,也叫Socket编程

代码示例如下:

例一:

//TCP编程例一:客户端给服务端发送信息。服务端输出此信息到控制台上
//网络编程实际上就是Socket的编程
public class TestTCP1 {

    //客户端
    @Test
    public void client() {
        Socket socket = null;
        OutputStream os = null;
        try {
            //1.创建一个Socket的对象,通过构造器指明服务端的IP地址,以及其接收程序的端口号
            socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
            //2.getOutputStream():发送数据,方法返回OutputStream的对象
            os = socket.getOutputStream();
            //3.具体的输出过程
            os.write("我是客户端,请多关照".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.关闭相应的流和Socket对象
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //服务端
    @Test
    public void server() {
        ServerSocket ss = null;
        Socket s = null;
        InputStream is = null;
        try {
            //1.创建一个ServerSocket的对象,通过构造器指明自身的端口号
            ss = new ServerSocket(9090);
            //2.调用其accept()方法,返回一个Socket的对象
            s = ss.accept();
            //3.调用Socket对象的getInputStream()获取一个从客户端发送过来的输入流
            is = s.getInputStream();
            //4.对获取的输入流进行的操作
            byte[] b = new byte[20];
            int len;
            while ((len = is.read(b)) != -1) {
                String str = new String(b, 0, len);
                System.out.print(str);
            }
            System.out.println("收到来自于:"+s.getInetAddress().getHostAddress()+"的连接");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //5.关闭相应的流以及Socket、ServerSocket的对象
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (s != null) {
                try {
                    s.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (ss != null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

结果:

client(客户端):

 

server(服务端):

我是客户端,请多关照 收到来自于:127.0.0.1的连接

例二:

//TCP编程例二:客户端给服务端发送信息,服务端将信息打印到控制台上,同时发送“已收到信息”给客户端
public class TestTCP2 {
    //客户端
    @Test
    public void client() {
        Socket socket = null;
        OutputStream os = null;
        InputStream is = null;
        try {
            socket = new Socket(InetAddress.getByName("127.0.0.1"), 8989);
            os = socket.getOutputStream();
            os.write("我是客户端".getBytes());
            //shutdownOutput():执行此方法,显式地告诉服务端发送完毕!
            socket.shutdownOutput();
            is = socket.getInputStream();
            byte[] b = new byte[20];
            int len;
            while ((len = is.read(b)) != -1) {
                String str = new String(b, 0, len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    //服务端
    @Test
    public void server() {
        ServerSocket ss = null;
        Socket s = null;
        InputStream is = null;
        OutputStream os = null;
        try {
            ss = new ServerSocket(8989);
            s = ss.accept();
            is = s.getInputStream();
            byte[] b = new byte[20];
            int len;
            while ((len = is.read(b)) != -1) {
                String str = new String(b, 0, len);
                System.out.print(str);
            }
            os = s.getOutputStream();
            os.write("已收到信息".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (s != null) {
                try {
                    s.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (ss != null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }
}

结果:

client:

已收到信息

server:

 我是客户端

例三:

//TCP编程例三:从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。并关闭相应的连接。
public class TestTCP3 {

    @Test
    public void client() {
        Socket socket = null;
        OutputStream os = null;
        FileInputStream fis = null;
        InputStream is = null;
        try {
            //创建Socket对象
            socket = new Socket(InetAddress.getByName("127.0.0.1"), 9898);
           //从本地获取一个文件发送给服务端
            os = socket.getOutputStream();
            fis = new FileInputStream(new File("1.png"));
            byte[] b = new byte[1024];
            int len;
            while ((len = fis.read(b)) != -1) {
                os.write(b, 0, len);
            }
            //3.终止输出流,告诉客户端已经写入发送完毕
            socket.shutdownOutput();
            //4.接收来自于服务端的信息
            is = socket.getInputStream();
            byte[] b2 = new byte[20];
            int len2;
            while ((len2 = is.read(b2)) != -1) {
                String str = new String(b2, 0, len2);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //5.关闭相应的流和Socket对象
            if (os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    @Test
    public void server() {
        ServerSocket ss = null;
        Socket socket = null;
        InputStream is = null;
        FileOutputStream fos = null;
        OutputStream os = null;
        try {
            //1.创建一个ServerSocket对象
            ss = new ServerSocket(9898);
            //2.调用其accept()方法,返回一个Socket对象
            socket = ss.accept();
            //3.将从客户端发送来的信息保存到本地
            is = socket.getInputStream();
            File file = new File("D:\\Java\\1.png");
            fos = new FileOutputStream(file);

            byte[] b = new byte[20];
            int len;
            while ((len = is.read(b)) != -1) {
                fos.write(b, 0, len);
            }
            System.out.println("收到来自于:"+socket.getInetAddress().getHostAddress()+"的文件!");
            //4.发送“接收成功”的信息反馈给客户端
            os = socket.getOutputStream();
            os.write("success!发送成功!".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭相应的流和Socket以及ServerSocket对象
            if (os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null){
                try {
                    fos.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 (ss != null){
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

结果:

client:

success!发送成功!

server:

收到来自于:127.0.0.1的文件!

 

UDP编程则通过“Datagram”(数据报)来发送与接收,发送端使用DatagramSocket,接收端使用DatagramPacket:

UDP网络通信的流程:

代码示例如下:

//UDP编程的实现
public class TestUDP {

    //发送端
    @Test
    public void send() {
        DatagramSocket ds = null;
        try {
            ds = new DatagramSocket();
            byte[] b = "你好,我是要发送的数据".getBytes();
            //创建一个数据报,每一个数据报不能大于64k,都记录着数据信息,发送端的IP、端口号
            //以及要发送到的接收端的IP、端口号
            DatagramPacket pack = new DatagramPacket(b, 0, b.length,
                    InetAddress.getByName("127.0.0.1"), 9090);

            ds.send(pack);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ds != null) {
                ds.close();
            }
        }

    }

    //接收端
    @Test
    public void receive() {
        DatagramSocket ds = null;
        try {
            ds = new DatagramSocket(9090);
            byte[] b = new byte[1024];
            DatagramPacket pack = new DatagramPacket(b, 0, b.length);
            ds.receive(pack);

            String str = new String(pack.getData(), 0, pack.getLength());
            System.out.println(str);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ds != null) {
                ds.close();
            }
        }

    }

}

结果:

send(发送端):

 

reveive(接收端):

你好,我是要发送的数据

 

 

--------------------------------------------------------------------------------我是分割线---------------------------------------------------------------------------------------

综合练习:

//客户端给服务端发送文本,服务端会将文本转成大写再返回给客户端
public class TestExer {

    public static void main(String[] args) {
        TestExer.client();
    }

    private static void client() {

        Socket socket = null;
        Scanner scanner = null;
        OutputStream os = null;
        InputStream is = null;
        try {
            socket = new Socket(InetAddress.getByName("127.0.0.1"), 9191);
            os = socket.getOutputStream();
            System.out.println("请输入多个字符:");
            scanner = new Scanner(System.in);
            String input = scanner.next();
            os.write(input.getBytes());
            socket.shutdownOutput();

            is = socket.getInputStream();
            byte[] b = new byte[10];
            int len;
            while ((len = is.read(b)) != -1) {
                String str = new String(b, 0, len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (scanner != null) {
                scanner.close();
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }


    @Test
    public void server() {
        ServerSocket ss = null;
        Socket s = null;
        InputStream is = null;
        OutputStream os = null;
        try {
            ss = new ServerSocket(9191);
            s = ss.accept();
            os = s.getOutputStream();
            is = s.getInputStream();
            byte[] b = new byte[10];
            int len;
            StringBuilder str = new StringBuilder();
            while ((len = is.read(b)) != -1) {
                String str1 = new String(b, 0, len);
                str.append(str1);
            }
            System.out.println("接收到的数据是:" + str);

            String strUpperCase = str.toString().toUpperCase();
            os.write(strUpperCase.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (s != null) {
                try {
                    s.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (ss != null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

结果:

client:

请输入多个字符:
asfsfdgfdhkfhmoirejioewnifnesonfniesionda
ASFSFDGFDHKFHMOIREJIOEWNIFNESONFNIESIONDA

server:

接收到的数据是:asfsfdgfdhkfhmoirejioewnifnesonfniesionda

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值