day26-Java网络编程

26.02_网络编程三要素之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 //两个::代表省略了中间的0
  • 1a2b:0000:aaaa::aabb:1f2f

26.03_网络编程三要素之端口号概述(掌握)

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

26.04_网络编程三要素协议(掌握)

  • 为计算机网络中进行数据交换而建立的规则、标准或约定的集合。
  • UDP (类似发短信,对方可以不开机,甚至是假号码)
    • 面向无连接,数据不安全,速度快。不区分客户端与服务端。
  • TCP (类似打电话,拨通才能打通话,http的底层就是TCP)
      * 面向连接(三次握手),数据安全,速度略低。分为客户端和服务端。
    • 三次握手: 1客户端先向服务端发起请求, 2服务端响应请求, 3传输数据

26.05_Socket通信原理图解(了解)

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

26.06_网络编程(UDP传输)(了解)

  • 1.发送Send
byte[] d = "你好啊!".getBytes();
InetAddress ip = InetAddress.getByName("127.0.0.1");

DatagramSocket socket = new DatagramSocket(); //创建socket,相当于是码头,随机端口号
// 四个参数是: 数据、数据长度、地址、端口号 
DatagramPacket data = new DatagramPacket(d, d.length, ip, 3001);
socket.send(data);
  • 2.接收Receive
DatagramSocket socket = new DatagramSocket(3001); //指定端口号,创建socket,相当于创建码头
DatagramPacket data = new DatagramPacket(new byte[1024], 1024); //相当于创建集装箱
socket.receive(data);
socket.close();

byte[] arr = data.getData();  //获取数据
int len = data.getLength();  //获取有效的字节个数
System.out.println(new String(arr, 0,len));
  • 3.接收方获取ip和端口号
String ip = packet.getAddress().getHostAddress();
int port = packet.getPort();

26.07_网络编程(UDP传输优化)

  • 接收端Receive
DatagramSocket socket = new DatagramSocket(3001); //指定端口号,创建socket,相当于创建码头
DatagramPacket data = new DatagramPacket(new byte[1024], 1024); //相当于创建集装箱
while(true) {
    socket.receive(data);
    byte[] arr = data.getData();  //获取数据
    int len = data.getLength();  //获取有效的字节个数
    System.out.println("收到内容: " + new String(arr, 0,len));
    System.out.println("对方地址: " + data.getAddress().getHostAddress());
    System.out.println("端口: " + data.getPort() + "\r\n");
}
  • 发送端Send
Scanner sc = new Scanner(System.in);
System.out.println("请输入发送的内容:");
DatagramSocket socket = new DatagramSocket(); //创建socket,相当于是码头
InetAddress ip = InetAddress.getByName("127.0.0.1");
while(true) {
    String line = sc.nextLine();
    if ("q".equals(line)) break;
    byte[] d = line.getBytes();  //数据
    // 四个参数是: 数据、数据长度、地址、端口号 
    DatagramPacket data = new DatagramPacket(d, d.length, ip, 3001);
    socket.send(data);   //发货
}
socket.close(); //底层是IO流,所以应该也关掉
sc.close();

也可以开启两个线程,一个线程发送信息,一个线程接收消息。

26.xx_GUI小程序遇到的懵逼知识点

这中间有一个GUI的聊天小程序,但是代码很多,就不粘贴了,毕竟Java桌面编程不是重点,目标是JavaEE,这里就将里面遇到的疑问点整理一下。

1.快捷键 Alt + Shift + L 把选中的变成局部变量
  Alt + Shift + z 选中代码,按此快捷键 快速try
  Ctrl+Shift+Numpad_Divede(小键盘的/号)  折叠全部方法
  Ctrl+Shift+Numpad_Multiply(小键盘的*号)  展开全部方法

2.匿名内部类里可以直接调用外部类的方法。
// 如下例子,写全的方式为: ClassName.this.method();   ClassName为外部类的名字
new Runnable() {
    public void run(){
        method();
    }   
};

2.1 如果外部变量是外部类的本地变量(如在方法中定义的变量),
    必须声明成final才能在内部类中使用,正常是不可以修改这个变量的,
    但如果变量搜索是对象,可以修改对象内的属性
2.2 如果外部变量是外部类的成员变量或类变量,内部类可以直接修改

3. 最常见的基本类型数组写法: int[] a = {1,2,3};     byte[] b = {1,2,3};
    这种写法的全写法是: int[] a = new int[]{1,2,3};   byte[] b = new byte[]{1,2,3}
所以见到  String str = new String(new byte[]{1,2,3});   不应该懵逼,这仅仅是标准写法

26.15_生成jar文件

Eclipse下,生成jar文件顺序是:

1.项目或类上右键 --> Export --> Java下的JAR file
2.选择好要导出jar的类和导出位置,点击Next>
3.再次点击Next>
4.选择Main Class之后,点击Finish
day26-Java网络编程_第1张图片
图一.png
day26-Java网络编程_第2张图片
图二.png

26.16_网络编程(TCP协议)(掌握)

  • 1.客户端
    • 创建Socket连接服务端(指定ip地址,端口号)通过ip地址找对应的服务器
    • 调用SocketgetInputStream()getOutputStream()方法获取和服务端相连的IO流
    • 输入流可以读取服务端输出流写出的数据
    • 输出流可以写出数据到服务端的输入流
  • 2.服务端
    • 创建ServerSocket(需要指定端口号)
    • 调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket
    • 调用SocketgetInputStream()getOutputStream()方法获取和客户端相连的IO流
    • 输入流可以读取客户端输出流写出的数据
    • 输出流可以写出数据到客户端的输入流

26.17_网络编程(TCP协议代码优化)

  • 客户端
Socket socket = new Socket("127.0.0.1", 3001); //指定ip和端口号
// 将InputStream 包装成 BufferedReader 便于直接读取一行数据
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 将OutputStream 包装成  PrintStream 好处是能直接写出换行和字符串
PrintStream ps = new PrintStream(socket.getOutputStream());

System.out.println(br.readLine());  //读取服务器的回话
ps.println("我是客户端,我就是想打个招呼而已。。"); //向服务器回话
socket.close();
  • 服务端
ServerSocket sever = new ServerSocket(3001);  //指定端口号
Socket socket = sever.accept();  //接收客户端的请求

// 将InputStream 包装成 BufferedReader 便于直接读取一行数据
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 将OutputStream 包装成  PrintStream 好处是能直接写出换行和字符串
PrintStream ps = new PrintStream(socket.getOutputStream());

ps.println("你好,我是服务器,有什么事?"); 
System.out.println(br.readLine());  //读取客户端的回复

26.18_网络编程(服务端是多线程的)(掌握)

ServerSocket sever = new ServerSocket(3001);  //指定端口号
while(true) {
    final Socket socket = sever.accept();  //接收客户端的请求
    new Thread(){
        public void run() {
            try {
                // 将InputStream 包装成 BufferedReader 便于直接读取一行数据
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                // 将OutputStream 包装成  PrintStream 好处是能直接写出换行和字符串
                PrintStream ps = new PrintStream(socket.getOutputStream());
                
                ps.println("你好,我是服务器,有什么事?"); 
                System.out.println(br.readLine());  //读取客户端的回复
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }.start();
}

26.19_网络编程(练习)

  • 客户端向服务器写字符串(键盘录入),服务器(多线程)将字符串反转后写回,客户端再次读取到是反转后的字符串
//反转字符串
private String reverString(String str) {
    return new StringBuffer(str).reverse().toString();
}

26.20_网络编程(客户端向服务器上传文件练习)

  • 客户端部分代码
Socket socket = new Socket("192.168.3.109",3002);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream ps = new PrintStream(socket.getOutputStream());

ps.println(file.getName());  // 发送文件名到服务端
String result = br.readLine(); //读取服务器返回结果
if ("存在".equals(result)) {
    System.out.println("您上传的文件已经存在,请不要重复上传..");
    socket.close();
    return;
}
System.out.println("文件不存在,开始上传...");
FileInputStream fis = new FileInputStream(file);  //开始读取文件到服务器
byte[] data = new byte[10 * 1024];
int len ;
while( (len = fis.read(data)) != -1) {
    ps.write(data, 0, len);
}

fis.close();
socket.close();
  • 服务端部分代码
ServerSocket server = new ServerSocket(3002);
System.out.println("服务器启动,端口号 3002 ");
while(true) {
    final Socket socket = server.accept();
    System.out.println("收到" + socket.getInetAddress().getHostAddress()+ "的请求,开始处理...");
    new Thread(){
        public void run() {
            try {
                InputStream is = socket.getInputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                PrintStream ps = new PrintStream(socket.getOutputStream());
                
                String fileName = br.readLine();
                File dir = new File("/Users/houwan/Java");
                if (!dir.exists())  dir.mkdir();  //不存在就创建文件夹
                File file = new File(dir, fileName); //封装成File对象
                if (file.exists()) {
                    ps.println("存在");
                    socket.close();  //关闭此次服务
                    return;
                }else ps.println("不存在");
                
                System.out.println("客户端开始上传文件...");
                FileOutputStream fos = new FileOutputStream(file);  //读取客户端上传的文件,保持到本地
                byte[] data = new byte[10 * 1024];
                int len ;
                while ( (len = is.read(data)) != -1) {
                    fos.write(data, 0, len);
                }
                fos.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        };
    }.start();
}

END。
我是小侯爷。
在魔都艰苦奋斗,白天是上班族,晚上是知识服务工作者。
如果读完觉得有收获的话,记得关注和点赞哦。
非要打赏的话,我也是不会拒绝的。

你可能感兴趣的:(day26-Java网络编程)