Just Do Java

Java 's Blog


  • 首页

  • 分类

  • 作者

  • 归档

  • 关于

计算机是由二进制组成的

发表于 2019-09-04 | 分类于 计算机组成原理

我们都知道,计算机的底层都是使用二进制数据进行数据流传输的,那么为什么会使用二进制表示计算机呢?或者说,什么是二进制数呢?在拓展一步,如何使用二进制进行加减乘除?二进制数如何表示负数呢?本文将一一为你揭晓。

阅读全文 »

【计算机网络】简单聊聊套接字 Socket

发表于 2019-09-04 | 分类于 计算机网络

Socket 由来:

在学习一个新知识之前,要去想它为什么会出现,它的出现解决了什么问题.这样印象才会深刻一些.

在同一个主机下,两个进程间的通讯是很容易,直接把各种通讯细节交给操作系统去做就 OK 了.但是如果两个进程是处于不同主机下呢?该如何进行通讯呢?而且在实际的应用场景中,是很复杂的,有的使用 TCP 协议,有的使用 UDP 协议,那么当我们使用不同的协议进行通信时,是不是就要使用不同的接口?同时还要处理不同协议的各种通讯细节,这样一来,是不是就增加了开发的难度,同时软件不容易进行扩展.

编程思想之一就是「面向对象」,同样,在遇到这种问题时,我能不能把不同协议的通信细节抽出来,这样程序员在使用的时候,直接调用,就不需要再关注协议本身了.而这就是 Socket 的由来.

它提供接口,来进行互联的不同主机之间的进程通信.你想要让不同主机之间通信? OK ,你直接调用我就行,至于我怎么实现,程序员不需要 care .

在上面的基础上,我们能够达成一个共识:如果一个应用,需要在客户端和服务端之间进行通信,那就需要创建一个 Socket 实例. 那么问题来了,我如何使用?

Socket 进行的是端到端的通信,中间经过多少局域网,路过多少路由器,我是不清晰的,所以能够设置的参数,也只是端到端协议之上的网络层和传输层. 在网络层, Socket 函数需要指定使用到的协议到底是 IPv4 还是 IPv6 ,分别对应设置为 AF_INET 和 AF_INET6 .此外,还需要说明你是使用 TCP 协议,还是 UDP 协议. TCP 协议是基于数据流的,所以设置为 SOCK_STREAM , UDP 是基于数据报的,因而设置为 SOCK_DGRAM .

基于 TCP 协议的 Socket 程序函数调用过程

客户端和服务端创建 Socket 之后, TCP 的服务端要先监听一个端口,一般是先调用 bind 函数,给这个 Socket 赋予一个 IP 地址和端口.为什么需要 IP 地址呢?有时候一台机器会有多个网卡,相应的就会有多个 IP 地址,可以选择监听所有的网卡,也可以选择监听一个网卡,这样只有发给这个网卡的包,才会给你.那我为什么还需要端口呢?你要知道,你写的是一个应用程序,当一个网络包来的时候,内核是需要通过 TCP 头里面的这个端口,来定位到你这个应用程序的.

此时,当服务端有了 IP 和端口号,就可以调用 listen 函数进行监听.在 TCP 的状态图中,有一个 listen 状态,当调用这个函数之后,服务端就进入了这个状态,这个时候客户端那边就可以发起连接了.

在内核中,为每个 Socket 维护了两个队列,一个是已经建立了连接的队列,说明此时三次握手已经完毕,处于 established 状态;一个是还没有完全建立连接的队列,也就是说这个时候三次握手还没完成,处于 syn_rcvd 的状态.

接下来,服务端调用 accept 函数,拿出一个已经完成的连接进行处理.如果客户端还没有完全建立连接,没别的办法,就等着咯.

在服务端等待的时候,客户端可以通过 connect 函数发起连接.现在参数中指明要连接的 IP 地址和端口号,然后开始发起三次握手.内核会给客户端分配一个临时的端口,一旦握手成功,服务端的 accept 就会返回另一个 Socket .

注意一下,在这里有一个经常考察的知识点,就是监听的 Socket 和真正用来传数据的 Socket 是两个,一个叫做「监听 Socket 」,一个叫做「已连接 Socket 」.

连接建立成功之后,双方就开始通过 read 和 write 函数来读写数据,就像往一个文件流里面写东西一样.之所以把 TCP 的 Socket 描述成一个文件流,是因为 Socket 在 Linux 中就是以文件的形式存在的.

在内核中, Socket 是一个文件,那对应就有文件描述符.每一个进程都有一个数据结构 task_struct ,里面指向一个文件描述符数组,来列出这个进程打开的所有文件的文件描述符.文件描述符是一个整数,是这个数组的下标.

这个数组中的内容是一个指针,指向内核中所有打开的文件的列表.既然是一个文件,就会有一个 inode ,只不过 Socket 对应的 inode 不像真正的文件系统一样,保存在硬盘上,而是在内存中.在这个 inode 中,指向了 Socket 在内核中的 Socket 结构.

在这个结构中,主要的是两个队列,一个是发送队列,一个是接收队列.在这两个队列里面保存的是一个缓存 sk_buff .这个缓存中能够看到完整的包的结构.

以上,就是基于 TCP 协议的 Socket 程序函数调用过程的一个描述

接下来说说基于 UDP 协议的 Socket 程序函数调用过程.

基于 UDP 协议的 Socket 程序函数调用过程 对于 UDP 来说,和 TCP 还是有些不一样的.首先, UDP 是没有连接的,也就不需要三次握手,也不需要调用 listen 和 connect ,但是 UDP 的交互仍然需要 IP 和端口号,那就需要 bind .

UDP 是没有维护连接状态的,也就不需要对每对连接建立一组 Socket ,而是只要有一个 Socket 就可以和多个客户端通信.也是因为没有连接状态,所以每次通信的时候,都调用 sendto 和 recvfrom ,这样才可以传入 IP 地址和端口.

写完这篇文章,我觉得我得去把< TCP/IP 协议详解> 这本书看看了~

以上就是想分享的一些内容了,感谢您的阅读哇~

阅读全文 »

谈谈 k8s 的本质

发表于 2019-09-03 | 分类于 k8s

当下 k8s 算是比较火的一个内容,那么它到底是什么呢,它为什么会这么火呢,它解决的是什么问题呢.

阅读全文 »

ShutdownHook- Java 优雅停机解决方案

发表于 2019-09-03 | 分类于 java基础

想象一下,如果你现在刚好在 word 上写需求文档,电脑突然重启。等待开机完成,你可能会发现写了一个小时文档没有保存,就这么没了。。。

阅读全文 »

工厂模式详解

发表于 2019-09-02 | 分类于 设计模式

工厂模式详解

阅读全文 »

面试官:都说阻塞 I/O 模型将会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?

发表于 2019-09-01 | 分类于 java线程

使用 Java 阻塞 I/O 模型读取数据,将会导致线程阻塞,线程将会进入休眠,从而让出 CPU 的执行权,直到数据读取完成。这个期间如果使用 jstack 查看线程状态,却可以发现Java 线程状态是处于 RUNNABLE,这就和上面说的存在矛盾,为什么会这样?

阅读全文 »

Java 集合框架全整理

发表于 2019-09-01

本篇文章的形式结构:

  • 以一个总图开头,了解Java集合框架都包括哪些主要部件;
  • 分别对各个部件进行大致的描述,描述其主要特征;
  • 以总结的形式结尾,并给出各个部件的优劣性对比表格;
  • 部分关于集合框架的面试题。
阅读全文 »

分布式系统面试系列02-Spring Cloud 的底层架构原理

发表于 2019-08-31 | 分类于 面试

分布式系统面试系列02-Spring Cloud 的底层架构原理,前面我们讲了 SpringCloud 的核心架构,了解了有要构建一套分布式系统我们需要哪些组件。今天以SpringCloud 为例,讲解一下它的核心组件的原理。

阅读全文 »

分布式系统面试系列04-服务注册中心如何进行选型的?服务发现慢遇到了么?怎么解决?

发表于 2019-08-31 | 分类于 面试

上家公司我们的技术栈是基于 SpringCloud ,注册中心默认的也是使用Eureka,但是出来面试的时候被问到了关于注册中心的选型是怎么来做的。今天这篇整好梳理一下服务注册中心如何来进行选型,还有服务发现慢的问题都是怎么来解决的,希望对大家有所帮助。

阅读全文 »

分布式系统面试系列03-Dubbo 的底层原理

发表于 2019-08-31 | 分类于 面试

分布式系统面试系列02-Dubbo 的底层原理,前面我们讲了 SpringCloud 核心组件的底层原理,同样的,作为微服务里面的另外一大派系Dubbo ,使用的也是蛮多的,很多时候面试也会考到。

阅读全文 »

Java Grammar:数组

发表于 2019-08-31 | 分类于 java基础

数组,一种应用非常广泛的数据结构,简单地来说就是一组类型相同且无序的元素的存储在固定长度且有序**的内存空间。

阅读全文 »

SpringBoot 速记

发表于 2019-08-28 | 分类于 SpringBoot

结束了前面的《Spring 源码深度学习》,这个八月给自己放松了一下,看了几本小说和电视剧,还有写一个工作中用到的小工具,周报数据渲染的前端界面(前端是真的难)。

当然技术上的学习也要注意,所以看了松哥写的《Spring Boot + Vue 全栈开发》,来系统学习 SpringBoot,下面是简单的速记,根据使用场景可以快速定位到知识点:

Demo 脚手架项目地址:

https://github.com/Vip-Augus/springboot-note

阅读全文 »

Java 网络编程:必知必会的 URL 和 URLConnection

发表于 2019-08-27 | 分类于 网络编程

java.net.URL 类将 URL 地址进行了封装,并提供了解析 URL 地址的基本方法,比如获取 URL 的主机名和端口号。java.net.URLConnection 则代表了应用程序和 URL 之间的通信链接,可用于读取和写入此 URL 引用的资源。

URLConnection 看起来只是比 URL 多了一个 Connection,它们之间的关系也仅限于此吗?

阅读全文 »

rocketmq 部署启动指南-Docker 版

发表于 2019-08-26 | 分类于 消息队列

最近学习使用 rocketmq,需要搭建 rocketmq 服务端,本文主要记录 rocketmq 搭建过程以及这个过程踩到的一些坑。

阅读全文 »

Spring 系列之定时任务—— Scheduled

发表于 2019-08-25 | 分类于 spring

人生有涯,学海无涯

Spring 的定时任务想必大家多多少少都用过,经过 Spring 团队的封装,大家使用起来非常的方便和简洁,那关于 定时任务的真正使用还有哪些你不知道的事呢?下面我们一起来看一下吧。

阅读全文 »

不知道如何实现服务的动态发现?快来看看 Dubbo 是如何做到的

发表于 2019-08-23 | 分类于 Dubbo

上篇文章如果有人问你 Dubbo 中注册中心工作原理,就把这篇文章给他大致了解了注册中心作用以及 Dubbo Registry 模块源码,这篇文章将深入 Dubbo ZooKeeper 模块,去了解如何实现服务动态的发现。

阅读全文 »

Effective Java - 覆盖 equals 时总要覆盖 hashCode

发表于 2019-08-22 | 分类于 Effective , Java

在每个覆盖了equals 方法的类中,都必须覆盖 hashCode 方法。如果不这样做的话,就会违反 hashCode 的通用约定,从而导致该类无法结合所有的给予散列的集合一起正常运作。这类集合包括 HashSet、HashMap,下面是Object 的通用规范:

阅读全文 »

Object 中有哪些常用方法?

发表于 2019-08-21 | 分类于 java基础

「Object 中有哪些常用方法?」这是个基础的问题,面试了中问了很多人,都卡壳了?!今天一起看看。

阅读全文 »

怎么破坏单例模式和怎么防止单例模式被破坏

发表于 2019-08-21 | 分类于 设计模式

怎么破坏单例模式和怎么防止单例模式被破坏

阅读全文 »

Effective Java - 覆盖equals遵守的约定

发表于 2019-08-20 | 分类于 Effective , Java

避免重写 equals 方法

重写equals 方法看起来很简单,但是还会有多种方式导致出错,后果可能是严重的。最简单,最容易避免出错的方式是避免重写equals方法,采用这种方式的每个类只需要和自己对比即可,这样永远不会出错。如果满足了以下任何一个约定,也能产生正确的结果:

阅读全文 »
1 … 17 18 19 … 26
Java Geek Tech

Java Geek Tech

一群热爱 Java 的技术人

514 日志
113 分类
24 作者
RSS
GitHub 知乎
Links
  • 纯洁的微笑
  • 沉默王二
  • 子悠
  • 江南一点雨
  • 炸鸡可乐
  • 郑璐璐
  • 程序通事
  • 懿
© 2019 - 2021 Java Geek Tech
由 Jekyll 强力驱动
主题 - NexT.Mist