「网络基础」网络套接字、端口、IP、协议、TCP与UDP,一样都没少


网络套接字

源IP地址和目的IP地址以及源端口号和目的端口号的组合称为网络套接字,用于标识客户端请求的服务器和服务;应用程序可以通过套接字打开、读写、关闭数据,允许应用程序在网络中加入I\O,与网络中的其他应用程序进行通信。

传输层实现端到端的通信,每个传输层连接有两个端点,那么,这个连接的端点是什么呢?既不是主机的IP地址,也不是某个应用进程,更也不是传输层的协议端口;而是套接字(socket)。每一个传输层连接唯一地被通信两端的两个端点(即两个套接字)所确定。

根据RFC793的定义:IP地址和端口号组合起来就构成了套接字。套接字,实际上是一个通信端点,每个套接字都有一个套接字序号,包括主机的IP地址与一个16位的主机端口号,展现形式是点分十进制的IP地址后面写上端口号,中间用冒号或逗号隔开,即:主机IP地址:端口号,比如,113.301.151.231:23就是一个套接字。

两个应用程序之间的数据传输要通过套接字来完成。当两个网络应用程序进行通信时,其中的一个网络应用程序将要传输的信息写入它所在主机的Socket中,然后该Socket通过网络接口卡的传输介质将这段信息发送给另一台主机的Socket中,使这段信息能传送到其他程序中。

TCP/IP的核心内容被封装在操作系统中,并向外提供了编程接口,如果应用程序要使用TCP/IP,可以通过系统提供的TCP/IP的编程接口来实现。在Windows环境下,网络应用程序编程接口称作Windows Socket,Linux 下Linux socket API存在头文件sys/socket.h中。


网络编程

通过调用套接字接口来实现进程间通信的程序设计就是网络编程。利用网络编程便可以实现同一系统中不同进程之间的通信,更是可以通过网络连接实现不同系统中多个进程的通信,比如:QQ 、微信等。

也正是因为网络编程的出现,才能实现现如今大型网络游戏的多人竞技,若是没有网络,游戏再怎么发展也只是单机游戏。


网络编程三要素

  1. IP地址:能够确定是哪一台主机
  2. 端口号:能够确定主机上的某个进程
  3. 网络通信协议:制定网络通信、数据交互的规则


Java 中的网络编程:java 对网络编程也提供了很好的支持,java 中关于网络编程的api位于java.net包下。

网络基础

IP,即Internet Protocol,网际互连协议的缩写,简称“网协”;是TCP/IP体系中的网络层协议,为计算机网路互连通信而设计,IP地址具有唯一性。

IP地址根据网络通讯协议的不同,有IPv4和IPv6两种:

  • IPv4:网际协议版本4(全称 Internet Protocol version 4,简称IPv4),又称互联网通信协议第四版,比如:192.168.0.7
  • IPv6:互联网协议第6版,全称 Internet Protocol Version 6,简称IPv6,是互联网工程任务组(IETF)为替代IPv4而设计的下一代IP协议,其地址数量号称可以为全世界的每一粒沙子编上一个地址,地址比如:1080:0:0:0:8:800:200C:417A


IP地址编址方案,IP地址编址方案将IP地址空间划分为A、B、C、D、E五类,其中A、B、C是基本类,D、E类作为多播和保留使用。

  • A类: 10.0.0.0 -- 10.255.255.255
  • B类:172.16.0.0 -- 172.31.255.255
  • C类: 192.168.0.0 -- 192.168.255.255
  • D类:组播地址,224.0.0.0~239.255.255.255,这个范围内的每个IP地址,都代表一组特定的主机


本机IP地址

  • 127.0.0.1
  • localhost


Java 中的IP地址

在Java中,使用InetAddress类来表示IP地址,InetAddress类有两个子类:Inet4Address类 和 Inet6Address类,分别对应IPv4和IPv6。

InetAddress类的使用也很简单,demo如下所示:

public class InetAddressDemo {      public static void main(String[] args) throws Exception {          InetAddress ip = InetAddress.getLocalHost();         System.out.println("ip: " + ip.toString());         System.out.println("hostName: " + ip.getHostName());         System.out.println("hostAddress: " + ip.getHostAddress());         System.out.println("localHost: " + InetAddress.getLocalHost());         System.out.println("isReachable: " + InetAddress.getLocalHost().isReachable(1000));      }  }

上述demo运行结果如下所示:

ip: SHISAN-WIN10/192.168.44.1 hostName: SHISAN-WIN10 hostAddress: 192.168.44.1 localHost: SHISAN-WIN10/192.168.44.1 isReachable: true


端口(port)

端口,英文port的中文名称,常见于各类网络技术文档,可以认为是设备与外界通讯交流的出口。端口可分为虚拟端口物理端口,虚拟端口指计算机内部或交换机路由器内的端口,对普通用户不可见,例如计算机中的80、21、23等端口;而物理端口是位于设备外部的可见端口,比如电脑主机的RJ45网口,交换机、路由器、集线器等的RJ45端口,电话使用的RJ11插口等都属于物理接口。


协议端口

如果把IP地址比作一栋建筑,端口就是出入这栋建筑的门,建筑可以有多个门;同理,IP地址的端口也可以有多个,而且会比门的数量多得多,因为一个IP地址的端口可以有65536(65536 = 2^16)个之多;端口是通过端口号来标记的,端口号只有整数,范围是从0 到65535(2^16-1),共计65536个。因此,端口的使用需要注意:

  • 在同一个计算机系统中,端口不能重复;若端口重复,会引发端口冲突而导致系程序运行错误;
  • 在开发中,经常会自定义端口,在自定义端口时尽量选择10000以后的,避免和系统现有的程序冲突;


协议

协议(protocol),全称是网络协议,是要通信的计算机双方必须共同遵从的一组约定,如怎样建立连接、通信双方如何互相识别、如何保证通信的顺利完成等,网络通信协议的三要素:语法、语义、时序。只有双方都按照通信规则建立连接,通信才能完成。

  1. 语法:协议中数据和要传输的信息的结构或格式;
  2. 语义:发出何种控制信息,可以完成何种动作,又会做出何种响应;
  3. 时序(同步):即事件实现顺序的详细说明。


网络模型各层中的网络协议:

下面是一些常见的网络协议:

  • http:超文本传输协议资源,基本所有面向用户的网络应用都是使用http协议进行通信的
  • https:用安全套接字层传送的超文本传输协议
  • ftp :文件传输协议
  • mailto:电子邮件地址
  • file:当地电脑或网上分享的文件,当我们用浏览器打开本地文件时便会看到这个协议


MIME 编码

在因特网上有很多的不同类型的资源,HTTP协议要为每种类型的资源打上于是MIME类型标签,依此来描述其传输的资源类型。

MIME,全称是Multipurpose Internet Mail Extension,即“多用途因特网邮件扩展”,最初的设计是为了解决在不同的电子邮件系统之间来回搬移报文时存在的问题,但由于其出色的表现,所以,在HTTP 协议中也继续使用,使用其来标记资源文件类型。

MIME 类型是一种文本标记,其内容由一种主要的资源类型和一个子类型组成,中间使用“/”分隔。在HTTP协议中使用首部中的Content-type字段来表示,常见的MIME类型有数百个,以下是一些常见的:

  • text/html:表示html格式的文本文档;
  • text/plain:表示ASCII格式的文本文档;
  • image/jpeg:表示jpeg格式的图片;
  • image/gif:表示gif格式的图片;
  • video/quicktime:表示apple的QuickTime电影类型;
  • application/vnd.ms-powerpoint:表示微软的ppt文档;


URI、URL、URI

URI:统一资源标识符(Uniform Resource Identifier,简称URI),是一个用于标识联网资源名称的字符串,能够在世界范围内唯一标识某一资源。URI有两种形式,即URL和URN。

URL:统一资源定位符,是资源标识符最常见的形式,用于定位某一互联网上的资源,是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,使用URL可以明确说明如何从一个精确、固定的位置获取资源。

大部分的URL,都是由三部分组成:

  1. scheme:这里通常是协议头,如:http,https;
  2. 服务器地址:服务器地址一般指的就是我们常说的域名,比如:baidu.com;
  3. 资源位置:跟在域名之后的部分,比如:/index,其指定了服务器上的某个资源;

互联网上的每个资源都有一个唯一的URL,它会指出文件的位置以及客户端的处理方式,现在几乎所有的URI都是URL,所以,平常所说的URI指的就是URL。


URN:统一资源名,URN是作为特定内容的唯一名称使用的,而且与资源所在的位置无关,因此,使用URN,就不必担心因资源迁移而导致无法访问的问题。此外,还可以使用同一个名称通过多种网络协议来访问资源。

比如:urn:ietf:rfc:2141 可以用来命名RFC 2141文档,而不闭担心其位于何处。


TCP、UDP

在传输层中的TCP协议和UDP协议在网络编程会经常使用到,下面就来介绍介绍:

  • TCP :面向连接(经历三次握手)、传输可靠(保证数据正确性,保证数据顺序)、用于传输大量数据(流模式)、速度慢,建立连接需要开销较多(时间,系统资源)。 工作模式在服务端和客户端之间进行。
  • UDP:面向非连接、传输不可靠(容易发生丢包[,导致数据丢失)、用于传输少量数据(数据报包模式)、速度快。工作模式在发送端和接收端客户端之间进行。


在所有的网络编程语言中都提供了对TCP协议和UDP协议的支持,Java 同样也不例外,下面就通过两个demo来展示:

Java 中的TCP

服务端:Server.java

public class Server {      public static void main(String[] args) throws Exception {         String data = "我是tcp的服务端";          // 创建TCP服务端,指定端口为8888         ServerSocket serverSocket = new ServerSocket(8888);         System.out.println("服务端已就绪!");         // 允许客户端建立连接         boolean accept = true;         while (accept) {             Socket client = serverSocket.accept();             System.out.println("客户端 : " + client.getInetAddress() + " 已连接。");             // 通过客户端的输出流,给客户端输出数据             PrintStream print = new PrintStream(client.getOutputStream());             print.println(data);             print.close();         }         serverSocket.close();     }  }


客户端:Client.java

public class Client {      public static void main(String[] args) throws Exception {         // 穿件客户端,与服务端建立连接         Socket client = new Socket("localhost", 8888);         // 输出服务端输入的数据         Scanner scanner = new Scanner(client.getInputStream());         while (scanner.hasNextLine()) {             String line = scanner.nextLine();             System.out.println(line);         }         scanner.close();         client.close();     }  }


记得要先运行服务端,再运行客户端。不然,会有意想不到的结果哦。


Java 中的UDP

发送端:Send.java

public class Send {      public static void main(String[] args) throws Exception {         String data = "我是udp的发送端";         // 创建发送端,端口为13000         DatagramSocket sender = new DatagramSocket(13000);         // 发送数据         DatagramPacket dp = new DatagramPacket(                 data.getBytes(), // 发送的数据                 data.getBytes().length,  // 发送的数据的长度                 InetAddress.getLocalHost(), // 接收端的ip                 14000); // 接收端的端口          sender.send(dp);         sender.close();      } }


接收端:Receive.java?

public class Receive {      public static void main(String[] args) throws Exception {         // 床架接收端对象         DatagramSocket receiver = new DatagramSocket(14000);         byte[] buffer = new byte[1024];         // 接收数据         DatagramPacket dp = new DatagramPacket(buffer, 1024);         receiver.receive(dp);         // 打印接收到的数据         String msg = new String(dp.getData(), 0, dp.getLength());         System.out.println("接收到的数据:" + msg);     }  }

先运行接收端,再运行发送端即可。


完结。老夫虽不正经,但老夫一身的才华

版权声明:

作者: freeclashnode

链接: https://www.freeclashnode.com/news/article-1310.htm

来源: FreeClashNode

文章版权归作者所有,未经允许请勿转载。

免费节点实时更新

热门文章

最新文章

归档