黑马程序员技术交流社区

标题: 【济南中心】JAVA编程阶梯:基础篇之第二十六章 [打印本页]

作者: 小鲁哥哥    时间: 2016-10-30 21:44
标题: 【济南中心】JAVA编程阶梯:基础篇之第二十六章
本帖最后由 小鲁哥哥 于 2016-10-30 21:46 编辑

【济南中心】JAVA编程阶梯:基础篇之第二十六章

网络编程概述
计算机网络
是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
网络编程
就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换


网络编程三要素之IP
每个设备在网络中的唯一标识
每台网络终端在网络中都有一个独立的地址,我们在网络中传输数据就是使用这个地址。
ipconfig:查看本机IP192.168.12.42
ping:测试连接192.168.40.62
本地回路地址:127.0.0.1 255.255.255.255是广播地址
IPv4:4个字节组成,4个0-255。大概42亿,30亿都在北美,亚洲4亿。2011年初已经用尽。
IPv6:8组,每组4个16进制数。
1a2b:0000:aaaa:0000:0000:0000:aabb:1f2f
1a2b::aaaa:0000:0000:0000:aabb:1f2f
1a2b:0000:aaaa::aabb:1f2f
1a2b:0000:aaaa::0000:aabb:1f2f
1a2b:0000:aaaa:0000::aabb:1f2f


网络编程三要素之端口号概述
每个程序在设备上的唯一标识
每个网络程序都需要绑定一个端口号,传输数据的时候除了确定发到哪台机器上,还要明确发到哪个程序。
端口号范围从0-65535
编写网络应用就需要绑定一个端口号,尽量使用1024以上的,1024以下的基本上都被系统程序占用了。
常用端口
mysql: 3306
oracle: 1521
web: 80
tomcat: 8080
QQ: 4000
feiQ: 2425


网络编程三要素协议
为计算机网络中进行数据交换而建立的规则、标准或约定的集合。
UDP
    面向无连接,数据不安全,速度快。不区分客户端与服务端。
TCP
  面向连接(三次握手),数据安全,速度略低。分为客户端和服务端。
    三次握手: 客户端先向服务端发起请求, 服务端响应请求, 传输数据


Socket套接字
    网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。
    通信的两端都有Socket。
    网络通信其实就是Socket间的通信。
    数据在两个Socket间通过IO流传输。
    Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所对应的IP和port。


UDP传输
[Java] 纯文本查看 复制代码
                // 发送端:
                class UDPSend {
                        public static void main(String[] args) {
                                // 创建DatagramSocket, 随机端口号
                                DatagramSocket ds = new DatagramSocket();
                                byte[] buf = "这是UDP发送端".getBytes();
                                // 创建DatagramPacket, 指定数据, 长度, 地址, 端口

                                DatagramPacket dp = new DatagramPacket(buf, buf.length,
                                                InetAddress.getByName("192.168.1.253"), 10000);
                                // 使用DatagramSocket发送DatagramPacket
                                ds.send(dp);
                                // 关闭DatagramSocket
                                ds.close();
                        }
                }
                // 接收端
                class UDPRece {
                        public static void main(String[] args) throws Exception {
                                // 创建DatagramSocket, 指定端口号
                                DatagramSocket ds = new DatagramSocket(10000);
                                // 创建DatagramPacket, 指定数组, 长度
                                byte[] buf = new byte[1024];
                                // 使用DatagramSocket接收DatagramPacket
                                DatagramPacket dp = new DatagramPacket(buf, buf.length);
                                ds.receive(dp);// 将发送端发送的数据包接收到接收端的数据包中
                                String ip = dp.getAddress().getHosyAddress();// 获取发送端的ip
                                String data = new String(dp.getData(), 0, dp.getLength());// 获取数据
                                int port = dp.getPort();// 获取发送端的端口号
                                sop(ip + ":" + data + ":" + port);
                                ds.close();
                        }
                }

UDP传输优化
[Java] 纯文本查看 复制代码
                // 接收端Receive
                DatagramSocket socket = new DatagramSocket(6666); // 创建socket相当于创建码头
                DatagramPacket packet = new DatagramPacket(new byte[1024], 1024); // 创建packet相当于创建集装箱

                while (true) {
                        socket.receive(packet); // 接收货物
                        byte[] arr = packet.getData();
                        int len = packet.getLength();
                        String ip = packet.getAddress().getHostAddress();
                        System.out.println(ip + ":" + new String(arr, 0, len));
                }
                // 发送端Send
                DatagramSocket socket = new DatagramSocket(); // 创建socket相当于创建码头
                Scanner sc = new Scanner(System.in);

                while (true) {
                        String str = sc.nextLine();
                        if ("quit".equals(str))
                                break;
                        DatagramPacket packet = // 创建packet相当于创建集装箱
                        new DatagramPacket(str.getBytes(), str.getBytes().length,
                                        InetAddress.getByName("127.0.0.1"), 6666);
                        socket.send(packet); // 发货
                }
                socket.close();
        }

UDP传输多线程
[Java] 纯文本查看 复制代码
public class Demo {

        public static void main(String[] args) {
                new Receive().start();

                new Send().start();
        }

}

class Receive extends Thread {
        public void run() {
                try {
                        DatagramSocket socket = new DatagramSocket(6666); // 创建socket相当于创建码头
                        DatagramPacket packet = new DatagramPacket(new byte[1024], 1024); // 创建packet相当于创建集装箱

                        while (true) {
                                socket.receive(packet); // 接收货物
                                byte[] arr = packet.getData();
                                int len = packet.getLength();
                                String ip = packet.getAddress().getHostAddress();
                                System.out.println(ip + ":" + new String(arr, 0, len));
                        }
                } catch (IOException e) {

                        e.printStackTrace();
                }
        }
}

class Send extends Thread {
        public void run() {
                try {
                        DatagramSocket socket = new DatagramSocket(); // 创建socket相当于创建码头
                        Scanner sc = new Scanner(System.in);

                        while (true) {
                                String str = sc.nextLine();
                                if ("quit".equals(str))
                                        break;
                                DatagramPacket packet = // 创建packet相当于创建集装箱
                                new DatagramPacket(str.getBytes(), str.getBytes().length,
                                                InetAddress.getByName("127.0.0.1"), 6666);
                                socket.send(packet); // 发货
                        }
                        socket.close();
                } catch (IOException e) {

                        e.printStackTrace();
                }
        }
}

TCP协议
[Java] 纯文本查看 复制代码
        // 客户端:
                class TCPClient {
                        public static void main(String[] args) {
                                // 创建Socket连接服务端(指定ip地址,端口号)通过ip地址找对应的服务器
                                Socket s = new Socket("192.168.1.111", 10000);
                                // 调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的IO流
                                OutputStream os = s.getOutputStream();
                                // 输出流写出数据到服务端的输入流
                                out.write("这是TCP发送的数据".getBytes());
                                s.close();
                        }
                }
                // 服务端:
                class TCPServer {
                        public static void main(String[] args) {
                                // 创建ServerSocket(需要指定端口号)
                                ServerSocket ss = new ServerSocket(10000);
                                // 调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket
                                Socket s = ss.accept();

                                String ip = s.getInetAddress().getHostAddress();
                                sop(ip);
                                // 调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流
                                InputStream is = s.getInputStream();
                                byte[] buf = new byte[1024];
                                // 输入流读取客户端输出流写出的数据
                                int len = is.read(buf);
                                sop(new String(buf, 0, len));
                                s.close();
                                ss.close();
                        }
                }

TCP协议代码优化
[Java] 纯文本查看 复制代码
// 客户端
                Socket socket = new Socket("127.0.0.1", 9999); // 创建Socket指定ip地址和端口号
                InputStream is = socket.getInputStream(); // 获取输入流
                OutputStream os = socket.getOutputStream(); // 获取输出流
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                PrintStream ps = new PrintStream(os);

                System.out.println(br.readLine());
                ps.println("我想报名就业班");
                System.out.println(br.readLine());
                ps.println("爷不学了");
                socket.close();
                // 服务端
                ServerSocket server = new ServerSocket(9999); // 创建服务器
                Socket socket = server.accept(); // 接受客户端的请求
                InputStream is = socket.getInputStream(); // 获取输入流
                OutputStream os = socket.getOutputStream(); // 获取输出流

                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                PrintStream ps = new PrintStream(os);

                ps.println("欢迎咨询传智播客");
                System.out.println(br.readLine());
                ps.println("报满了,请报下一期吧");
                System.out.println(br.readLine());
                server.close();
                socket.close();

服务端是多线程的
[Java] 纯文本查看 复制代码
                ServerSocket server = new ServerSocket(9999); // 创建服务器
                while (true) {
                        final Socket socket = server.accept(); // 接受客户端的请求
                        new Thread() {
                                public void run() {
                                        try {
                                                BufferedReader br = new BufferedReader(
                                                                new InputStreamReader(socket.getInputStream()));
                                                PrintStream ps = new PrintStream(
                                                                socket.getOutputStream());
                                                ps.println("欢迎咨询传智播客");
                                                System.out.println(br.readLine());
                                                ps.println("报满了,请报下一期吧");
                                                System.out.println(br.readLine());
                                                socket.close();
                                        } catch (IOException e) {
                                                e.printStackTrace();
                                        }
                                }
                        }.start();
                }




作者: 929215141    时间: 2016-11-1 23:59
谢谢分享,!!赞一个!!
作者: 929215141    时间: 2016-11-2 00:00
谢谢分享,帮助很大,给楼主赞一个!!!
作者: Ev你微笑时好美    时间: 2016-11-3 09:59
好东西,支持一下
作者: aA772807986    时间: 2016-11-16 20:40
太给力了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2