JAVA基础-肆-网络编程

网络编程


概述

计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
网络编程目的传播交流信息,数据交换,通信
想要达到这个效果需要

  1. 准确定位网络的一台主机,eg: 10.21.49.248:端口号,定位到这个计算机上的某个资源
  2. 传输数据(如何进行通信)

javaweb: 网页编程 B/S架构(Browser/Server)
网络编程: TCP/IP C/S架构 (Client/Server)


网络通信的两个要素

通信双方的地址

  • ip
  • 端口号

规则:网络通信的协议
TCP/IP参考模型:

OSI七层网络模型

物理层

主要解决两台物理机之间的通信,通过二进制比特流的传输来实现,二进制数据表现为电流电压上的强弱,到达目的地再转化为二机制机器码。网卡,集线器工作在这一层

数据链路层

在不可靠的物理介质上提供可靠的传输,接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,拆装为位流形式的数据转发到物理层。这一层在物理层提供的比特流的基础上,通过差错控制,流量控制方法,使用差错的物理线路编程无差错的数据链路。提供物理地址寻址功能。交换机工作在这一层。

网络层

将网络地址翻译成对应的物理地址,并决定如何将数据从发送方路由到接收方,通过路由选择算法为分组通过通信子网(communication subnet简称子网,是指网络中实现网络通信功能的设备及其软件的集合,包括通信设备,网络通信协议,通信控制软件,是网络的内层负责信息的传输)选择最佳路径,路由器工作在这一层。

传输层

传输层提供了进程间的逻辑通信,传输层向高层用户屏蔽了下面网络层的核心细节,使应用程序看起来像是在两个传输层实体之间有一条端到端的逻辑通信信道。

会话层

建立会话:身份验证,权限鉴定等;保持会话:对该会话进行维护,在会话维持期间两者可以随时使用这条会话传输局;断开会话:当应用程序或应用层规定的超时时间到期后,OSI会话层才会释放这条会话

表示层

对数据格式进行编译,对收到或发出的数据根据应用层的特征进行处理,如处理为文字,图片,音频,视频,文档等,还可以对压缩文件进行解压缩,对加密文件进行解密等。

应用层

提供应用层协议,如HTTP协议,FTP协议等等,方便应用程序之间进行通信。


IP

java.lang.Object
java.net.InetAddress

  • 唯一定位一台网络上的设备
  • 127.0.0.1 代表的是本机 localhost
  • ip地址的分类
    • ip地址分类: ipv4 ipv6
      • ipv4: 4个字节组成,一共32位,0~255,大概有42亿个组合,以十进制“.” 隔开;
      • ipv6: 8个无符号整数组成,一共128位,16进制,以":" 隔开;
    • 公网(互联网) - 私网(局域网)
      • ABCD类地址


        ABCD类地址
      • 192.168.xx.xx, 专门给组织内部使用的

  • 域名: 记忆IP问题

端口

端口表示计算机上一个程序的进程

  • 不同的进程有不同的端口号,用来区分软件
  • 被规定0~65535 ( 2的16次方)
  • TCP, UDP: 65535 * 2, 单个协议下端口号不可以冲突,不同协议可以重复
  • 端口分类
    • 公有端口: 0~1023
    • 程序注册端口: 1024~49151,分配给用户或者程序
      • Tomcat: 8080
      • MySQL: 3306
      • Oracle: 1521
    • 动态,私有端口: 49152~65535
      • netstat -ano 查看所有端口 // linux cmd指令
      • netstat -ano|findstr "5900" 查看指定端口
      • tasklist|findstr "8696" 查看指定端口的进程
      • ctrl + shift + esc 打开任务管理器
        不同电脑的进程间通信

通信协议

网络通信协议: 速率,传输码率,代码结构, 传输控制...

TCP/IP 协议簇

  • TCP: 用户传输协议 Transmission Control Protocol
  • UDP:用户数据报协议 User Datagram Protocol

TCP versus UDP

TCP

  • 连接,稳定

  • 三次握手 四次挥手


    三次握手

    四次挥手
  • 客户端,服务端

  • 传输完成,释放连接,效率低
    UDP

  • 不连接,不稳定

  • 客户端,服务端:没有明确的界限

  • 没有太多的限制

  • DDOS: 洪水攻击,用过量的垃圾文件一直发送堵塞端口


TCP

客户端

  1. 连接服务器的Socket
  2. 发送消息
package web.tcp;

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

// 客户端
public class TcpClientDemo1 {
    public static void main(String[] args) {
        Socket socket = null;
        OutputStream os = null;
        try {
            // 1.确定服务器地址
            InetAddress serverIp = InetAddress.getByName("127.0.0.1");
            int port = 9999;

            // 2.创建一个socket连接
            socket = new Socket(serverIp, port);

            // 3.发送消息 IO流
            os = socket.getOutputStream();
            os.write("我爱你,你爱我,蜜雪冰城甜蜜蜜".getBytes());

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

服务端

  1. 建立服务的端口 ServerSocket
  2. 等待用户的连接 accept
  3. 接收并处理收到的消息
package web.tcp;

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

// 服务端
public class TcpServerDemo01 {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream inputStream = null;
        ByteArrayOutputStream bas = null;

        try {
            // 1.生成一个地址
            serverSocket = new ServerSocket(9999);

            // 2.等待客户端连接
            socket = serverSocket.accept();

            // 3.读取客户端的消息
            inputStream = socket.getInputStream();
            // 管道流
            bas = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) != -1) {
                bas.write(buffer, 0, len);
            }

            System.out.println(bas);
            System.out.println("连接结束!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bas != null) {
                    bas.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
                if (socket != null) {
                    socket.close();
                }
                if (serverSocket != null) {
                    serverSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

文件上传

客户端

package web.tcp;

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

public class TcpClientDemo02 {
    public static void main(String[] args) throws Exception {
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
        OutputStream os = socket.getOutputStream();

        FileInputStream fileInputStream = new FileInputStream(new File("/Users/bilibili/Desktop/picture/png/activity_life.png"));

        byte[] buffer = new byte[1024];
        int length;
        while ((length = fileInputStream.read(buffer)) != -1) {
            os.write(buffer, 0, length);
        }
        // 通知服务器,我已经结束了
        socket.shutdownOutput();

        // 确定服务器接收完毕才能够断开连接
        InputStream inputStream = socket.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer2 = new byte[1024];
        int length2;
        while((length2 = inputStream.read(buffer2)) != -1) {
            baos.write(buffer2, 0, length2);
        }
        System.out.println(baos);

        baos.close();
        inputStream.close();
        fileInputStream.close();
        os.close();
        socket.close();
    }

}

服务端

package web.tcp;

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

public class TcpServerDemo02 {
    public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = new ServerSocket(9000);
        Socket socket = serverSocket.accept();// 阻塞式监听,会一直等待客户端连接

        InputStream is = socket.getInputStream();
        FileOutputStream fos = new FileOutputStream(new File("receive.png"));
        byte[] buffer = new byte[1024];
        int length;
        while ((length = is.read(buffer)) != -1) {
            fos.write(buffer, 0, length);
        }

        // 通知客户端接收完毕
        OutputStream os = socket.getOutputStream();
        os.write("我接收完毕了,你可以断开".getBytes());

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

Tomcat

服务端

  • 自定义 S
  • Tomcat服务器 S
    客户端
  • 自定义 C
  • 浏览器 B

用法

到安装好的tomcat文件里的bin文件下打开terminal,执行

➜  bin > sudo sh startup.sh

当出现以下日志时,则证明成功启动。


tomcat_log

然后访问localhost:8080,如果可以打开网页则证明tomcat启动成功。然后网页的内容和资源文件都在webapps文件夹里,里面ROOT这个文件夹就对应着localhost:8080这个主页面,可以通过在后缀后面加其他文件夹的名字来访问其他子网页。

tomcat_webapp

例如:docs

tomcat_docs

还有一个有趣的贪吃蛇小游戏


tomcat_snake

其中整个页面的布局代码在index.jsp中。然后可以自己添加文件夹,放文件或者生成网页去访问。


tomcat_files.png

UDP

发短信:

  1. 无需连接
  2. 需要知道对方的ip地址
  3. 相关类DatagramPacket(发送), DatagramSocket(接收)

客户端
与TcpClient明显不同的一点就是如果TcpClient没有连接到对应的TcpServer是会报错的,提示Connection Refused。但是UdpClient不会。

public class UdpClientDemo01 {
  public static void main(String[] args) throws IOException {
    DatagramSocket datagramSocket = new DatagramSocket();  // 建立一个Socket

    String message = "hello world";
    byte[] bytes = message.getBytes();
    InetAddress localhost = InetAddress.getByName("localhost");
    int port = 9000;
    DatagramPacket data = new DatagramPacket(bytes, 0, bytes.length, localhost, port); // 建立要传输的数据
    
    datagramSocket.send(data);   // 传输数据
    datagramSocket.close();      // 关闭Socket
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354

推荐阅读更多精彩内容