Java 网络编程基础学习

学习过程是看毕向东老师的视频。


1.网络模型

OSI参考模型
应用层
表示层
会话层
传输层
网络层
数据链路层
物理层

面试的时候,技术总监最后和我说到这里时,我表示一脸蒙蔽,说不出这7层名字都是啥。


TCP/IP 参考模型
应用层
传输层
网络层
主机至网络层

根据我目前的了解,我是在最上层应用层开发。

网络通讯要素:

  • IP地址
  • 端口号
  • 传输协议

2 TCP与UDP

  • TCP(Transmission Control Protocol 传输控制协议)

在OSI中属于第四层传输层的协议。是一种面向连接的,可靠的,基于字节流的的传输层协议。在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层。

应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元(MTU)的限制)。之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。

TCP三次握手

TCP三次握手的过程如下:

  1. 客户端发送SYN(SEQ=x)报文给服务器端,进入SYN_SEND状态。
  2. 服务器端收到SYN报文,回应一个SYN(SEQ=y)ACK(ACK=x+1)报文,进入SYN_RECV状态。
  3. 客户端收到服务器端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态。

  • UDP(User Datagram Protocol用户数据报协议)

同TCP协议同层,UDP也是第四层传输层的协议。是无连接的,不可靠的,协议。

UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在第四层——传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。
与所熟知的TCP(传输控制协议)协议一样,UDP协议直接位于IP(网际协议)协议的顶层。根据OSI(开放系统互连)参考模型,UDP和TCP都属于传输层协议。UDP协议的主要作用是将网络数据流量压缩成数据包的形式。一个典型的数据包就是一个二进制数据的传输单位。每一个数据包的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。

以上主要摘抄百度百科。


3.TCP和UDP的特点

TCP特点

  • 建立连接,形成传输数据的通道
  • 在连接中进行大量的数据传输
  • 三次握手,可靠
  • 由于必须建立连接,效率稍低

UDP特点

  • 将数据、源和目的封装成数据包,不需要建立连接
  • 每个数据报的大小限制在64k
  • 不可靠,可能丢包
  • 由于不需要建立连接,所以速度快

常见的使用场景
UDP:聊天,视频会议
TCP:下载文件


4.Socket

网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个Socket。两个Socket间通信主通过IO。Socket进行通信所需要的协议不只有TCP/IP,在Java中主要就是TCP/IP协议。

TCP/IP协议

Transmission ControlProtocol/InternetProtocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议、Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成。TCP/IP 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的协议来完成自己的需求。
通俗而言:TCP负责发现传输的问题,一有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地。而IP是给因特网的每一台联网设备规定一个地址。


TCP通信需要SocketServerSocket两个类。
客户端对应Socket,服务端对应ServerSocket
TCP建立两个Socket的过程:
当客户端有Socket试图连接服务端某个目标端口时,监听这个服务端目标端口的ServerSocket就会接受(accept)这个客户端的Socket请求,ServerSocket并在服务端建立一个Socket来与客户端进行通信。这时,客户端和服务端便各有了一个Socket。


UDP客户端和服务端的两个Socket进行通信,需要DatagramSocketDatagramPacket这两个封装好的类。

DatagramSocket

This class represents a socket for sending and receiving datagram packets.

DatagramPacket

This class represents a datagram packet.

感觉英文反而容易理解一些。
DatagramPacket:把数据进行封装的数据报包。作用是用来实现无连接的包投递服务。
DatagramSocket:负责发送和接受数据报包。


5.UDP简单实例

客户端向服务端发送Hello World!

客户端代码:

public class UdpSend {

    public static void main(String[] args) {
        String info = "Hello World";
        int port = 10888;
        boolean b = sendMessage(info, port);
        if (b) {
            System.out.println("ok!!!");
        }
    }

    private static boolean sendMessage(String info, int port) {
        try {
            // 1 创建DatagragmSocket对象
            int me = 10887;
            DatagramSocket ds = new DatagramSocket(me);
            // 2 创建DatagramPacket对象
            byte[] buf = info.getBytes();// byte[]
            InetAddress address = InetAddress.getByName("192.168.0.103");// IP
            DatagramPacket dp = new DatagramPacket(buf, buf.length, address, port);
            // 3 发送数据
            ds.send(dp);
            // 4 关闭连接
            ds.close();

            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

在客户端代码中,客户端端口号为10887,服务端端口号为10888.
DatagramSocket构造方法中的端口号为自己的端口号10887。
DatagramPacket构造方法中也需要一个端口号,但这个端口号为服务端,接收DatagramPacket这个数据报包的DatagramSocket的端口号10888。


服务端代码:

public class UdpReceiver {
    public static void main(String[] args) {
        int port = 10888;
        receString(port);
    }

    private static void receString(int port) {
        try {
            // 1 创建DatagramSocket对象 确定端口
            DatagramSocket ds = new DatagramSocket(port);
            // 2 创建DatagramPacket
            byte[] buf = new byte[1024 * 8];
            DatagramPacket dp = new DatagramPacket(buf, buf.length);
            // 3 将接收到的数据放入DatagramPacket中
            ds.receive(dp);
            // 4 利用DatagramPacket的方法拿到具体的数据
            String ip = dp.getAddress().getHostAddress();
            int p = dp.getPort();
19行:       String info = new String(dp.getData(), 0, dp.getLength());
            System.out.println(ip + "\n" + info + "\n" + p);
            // 关闭连接
            ds.close();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

需要注意的是19行中,拿String数据时,通过dp.getLength()这个方法,根据DatagramPacket中数据的时机大小来确定。因为定义的buf的大小为1024 * 8

还有就是记得关闭连接。


6.TCP简单实例

客户端代码:

public class TcpClient {
    public static void main(String[] args) {
        String info = "Hello world!";
        boolean b = sendMessage(info);
        if (b) {
            System.out.println("ok");
        }
    }

    private static boolean sendMessage(String info) {
        int port = 10902;
        try {
            InetAddress address = InetAddress.getByName("192.168.0.103");
            // 1 建立Socket
            Socket socket = new Socket(address, port);
            // 2 拿到输出流
            OutputStream outputStream = socket.getOutputStream();
            // 3 写入数据
            outputStream.write(info.getBytes());
            // 4 关闭Socket
            socket.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

服务端代码:

public class TcpServer {
    public static void main(String[] args) {
        receInfo();
    }

    private static void receInfo() {
        try {
            // 1 建立ServerSocket
            ServerSocket serverSocket = new ServerSocket(10902);
            // 2 通过accept()拿到Socket
            Socket socket = serverSocket.accept();
            // 打印IP
            System.out.println(socket.getInetAddress().getHostAddress());
            // 3 通过Socket拿到输入流
            InputStream inputStream = socket.getInputStream();
            byte[] buf = new byte[1024];
            int len;
            // 4 读取数据
            while ((len = inputStream.read(buf)) != -1) {
                String info = new String(buf, 0, len);
                System.out.println(info);
            }
            // 5 关闭Socket和ServerSocket
            socket.close();
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

客户端Socket和服务端ServerSocket的端口号为一个。ServerSocket就是通过端口号和客户端的Socket通过accept()建立联系。


7.最后

UDP通信依赖DatagramSocketDatagramPacket
TCP通信依赖SocketServerSocket

Java Socket网络编程最基础的部分有了一点了解,还有很多东西就需要以后继续深入学习。有错误希望可以指出。: )

共勉。

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

推荐阅读更多精彩内容

  • 1. 网络编程概述 1.1 计算机网络 是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接...
    JackChen1024阅读 1,035评论 0 3
  • [TOC] 第十二章网络编程 网络编程概述 就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换。 网络...
    lutianfei阅读 657评论 1 7
  • iOS网络HTTP、TCP、UDP、Socket 知识总结OSI 七层模型我们一般使用的网络数据传输由下而上共有七...
    蜗牛也有梦想阅读 2,406评论 0 3
  • 定义 网络协议为计算机网络中进行数据交换而建立的规则、标准或约定的集合。网络协议主要由三个要素组成:语义、语法及时...
    FlyAndroid阅读 991评论 0 10
  • 晴空万里,抓住夏天的尾巴,出去走走。 211大巴姐妹们来萌一张 lily最满意的杰作,林氏笑容 大摄影师也来萌萌 ...
    柠檬公主阅读 524评论 0 0