Java网络编程概念,简单Socket编程

一、计算机网路基础概念

1、计算机网路  --百度百科

       计算机网络是指:将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。

       从逻辑功能上看,计算机网络是以传输信息为基础目的,用通信线路将多个计算机连接起来的计算机系统的集合,一个计算机网络组成包括传输介质和通信设备。

       虽然网络类型的划分标准各种各样,但是从地理范围划分是一种大家都认可的通用网络划分标准。按这种标准可以把各种网络类型划分为局域网(LocalArea Network, LAN)、城域网(Metropolitan Area Network,MAN)、广域网(Wide Area Network,WAN)和互联网(Internet,由无数的 LAN 和 WAN 组成)四种。

 

 2、网络编程模式

在网络通信中主要有两种模式的通信方式:客户机/服务器(Client/Server)模式,简称为C/S 模式和浏览器/服务器(Browser/Server)模式,简称 B/S 模式。

1. Client/Server 模式

客户机、服务器以及网络三者之间的关系图,使用这种模式的程序很多,例如:qq、游戏等,需要在本机上安装一个客户端,服务器运行在开发公司的机房。

使用 C/S 模式的程序,在开发时需要分别针对客户端和服务器端进行专门开发。

优点:由于客户端是专门开发的,表现力会更强。缺点:通用性差,维护压力较大。

2. Browser/Server 模式

用户使用浏览器作为客户端的这种模式叫作浏览器/服务器模式。

优点:只需开发服务器端即可,开发压力较小,不需要维护客户端。缺点:对浏览器的限制比较大,表现力不强。

 

3、网络协议

       为了减少网络设计的复杂性,绝大多数网络采用分层设计方法。分层设计方法,就是按照信息的流动过程将网络的整体功能分解为一个个的功能层,不同机器上的同等功能层之间采用相同的协议,同一机器上的相邻功能层之间通过接口进行信息传递。

网络上的计算机之间要通信就必须有一些约定,这些约定被称为网络通信协议。不同的计算机之间必须使用相同的通信协议才能进行通信。

      

       网络模型一般是指OSI七层参考模型TCP/IP四层参考模型

       开放系统互连参考模型 (Open System Interconnect 简称OSI)是国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合制定的开放系统互连参考模型,为开放式互连信息系统提供了一种功能结构的框架。

OSI先有模型后有协议,先有标准后进行实践;而TCP/IP则相反,先有协议和应用再提出了模型,且是参照的OSI模型。

TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议):TCP/IP协议是一个协议集合。所以统称为TCP/IP。在 TCP/IP 中包含一系列用于处理数据通信的协议:

  • TCP (传输控制协议) - 应用程序之间通信
  • UDP (用户数据包协议) - 应用程序之间的简单通信
  • IP (网际协议) - 计算机之间和计算机网络之间的通信
  • ICMP (因特网消息控制协议) - 针对错误和状态
  • DHCP (动态主机配置协议) - 针对动态寻址

1. TCP(transmission control protocol)传输控制协议协议:

TCP 用于应用程序之间的通信。当应用程序通过TCP与另一个应用程序通信时,它会发送一个通信请求。这个请求必须被送到一个确切的地址。在双方“三次握手”之后,TCP 将在两个应用程序之间建立一个全双工 (full-duplex) 的通信。

这个全双工的通信将占用两个计算机之间的通信线路,直到它被一方或双方关闭为止,关闭时会经历四次挥手。

(1)TCP三次握手

所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。

在socket编程中,这一过程由客户端执行connect来触发,整个流程如下图所示:

 

  • SYN:同步标志。表明同步序列编号栏有效。
  • ACK:确认标志。确认值(Acknowledgement),为1便是确认连接。
  • ack:确认编号(Acknowledgement Number),即接收到的上一次远端主机传来的seq然后+1,再发送给远端主机。提示远端主机已经成功接收上一次所有数据。
  • FIN:结束标志。

1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。

3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态。

完成三次握手,随后Client与Server之间可以开始传输数据了。

(2)TCP四次挥手

四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。

在socket编程中,这一过程由客户端或服务端任一方执行close来触发,整个流程如下图所示:

由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,如上图。

1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。

2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。

3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。

4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

(3)为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

建立连接时,服务端收到客户端建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。

关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。

 

2. UDP(user data protocol)用户数据报协议:

Internet 协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。

UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。

 

3. UDP与TCP区别:

      TCP :面向连接(经历三次握手)、传输可靠(保证数据正确性,保证数据顺序)、用于传输大量数据(流模式)、速度慢,建立连接需要开销较多(时间,系统资源)。

      UDP:面向非连接、传输不可靠(丢包[数据丢失])、用于传输少量数据(数据报包模式)、速度快。发送端和接收端

 

4. IP(Internet Protocol)协议

IP协议又称网际协议,是TCP/IP协议的核心。

它负责Internet上网络之间的通信,并规定了将数据报从一个网络传输到另一个网络所应遵循的规则。

IP协议不但定义了数据传输时的基本单元和格式,还定义了数据报的递交方法和路由选择。

此外,在TCP/IP网络中,主机之间进行通信所必需的地址,也是通过IP协议来实现的。

(1)IP地址

是指分配给用户上网使用的网际协议(英语:InternetProtocol,IP)的设备的数字标签。

       IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。

在TCP/IP协议中,这个标识号就是IP地址,它可以唯一标识一台计算机,

目前,IP地址广泛使用的版本是IPv4,它是由4个字节大小的二进制数来表示,由于二进制形式表示的IP地址非常不便记忆和处理,因此通常会将IP地址写成十进制的形式,每个字节用一个十进制数字(0-255)表示,数字间用符号“.”分开,如 “192.168.1.100”。

随着计算机网络规模的不断扩大,对IP地址的需求也越来越多,IPV4这种用4个字节表示的IP地址面临枯竭,因此IPv6 便应运而生了,IPv6使用16个字节表示IP地址,它所拥有的地址容量是IPv4的接近8×10^28倍,达到2^128-1个(全零的不能用),这样就解决了网络地址资源数量不够的问题。

(2)端口号

通过IP地址可以连接到指定计算机,但如果想访问目标计算机中的某个应用程序,还需要指定端口号。

在计算机中,不同的应用程序是通过端口号区分的。

端口号是用两个字节(16位的二进制数)表示的,它的取值范围是0~65535,其中,0~1023之间的端口号用于一些知名的网络服务和应用,用户的普通应用程序需要使用1024以上的端口号,从而避免端口号被另外一个应用或服务所占用。

 

 

二、Java网络编程基础概念

       网络编程的目的:就是直接或间接地通过网络协议与其他计算机进行通信。即通过使用套接字来达到进程间通信目的

Java为网络编程提供了支持包 java.net,该包下提供了InetAddress、ULRDecoder、URLEncoder、URL和URLConnection等等很多工具类,这些类可以让我们通过编程的形式访问Web服务器或者其他的服务器。

Java的网络编程主要涉及到的内容是Socket编程,倒不如说是Java的I/O编程,因为整个过程中关于服务端和客户端的socket创建也就那么两三行代码,其余的都是操作字节流,字符流等数据传输。

1、什么是Socket套接字呢?

       实现网络通信必须将两台计算机连接起来建立一个双向的通信链路,所以,源IP地址和目的IP地址以及源端口号和目的端口号的组合称为套接字。其用于标识客户端请求的服务器和服务。简单说,Socket套接字就是两台主机之间逻辑连接的端点。

套接字(Socket)是一个抽象出来的概念代表在端上的通信链路。       

TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。Socket,本质上就是一组接口,是对TCP/IP协议的封装和应用(程序员层面上)。    .

2、网络编程三要素

      IP地址、端口和协议(数据传递/交互的规则)

1. IP地址      

    在Java中,使用 java.net.InetAddress 类来表示IP地址

   

    //方法等
    public static void main(String[] args) throws IOException {
        /**
         * static InetAddress getLocalHost()
         *     返回本地主机。
         */
        InetAddress inetAddress = InetAddress.getLocalHost();
        System.out.println(inetAddress); // administrator/192.68.69.10
        /**
         * String getHostName()
         *      获取此IP地址的主机名。
         */
        System.out.println(inetAddress.getHostName()); //administrator
        /**
         * String getHostAddress()
         *      返回文本显示中的IP地址字符串。
         */
        System.out.println(inetAddress.getHostAddress()); //192.68.69.10
        /**
         * byte[] getAddress()
         *      返回此 InetAddress对象的原始IP地址。
         */
        System.out.println(inetAddress.getAddress());

        /**
         * static InetAddress getByName(String host)
         *     在给定主机名的情况下确定主机名称的IP地址。
         */
        inetAddress = InetAddress.getByName("www.baidu.com");
        System.out.println(inetAddress); //www.baidu.com/180.101.49.11
        /**
         * boolean isReachable(int timeout)
         *      测试该地址是否可达。
         */
        System.out.println(inetAddress.isReachable(3000)); //true
    }

2. 端口(port)

       在Java中,使用 java.net.InetSocketAddress 类来表示

      

    //方法等
    public static void main(String[] args) throws IOException {
        /** 构造器
         * InetSocketAddress(InetAddress addr, int port)
         *      从IP地址和端口号创建套接字地址。
         * InetSocketAddress(String hostname, int port)
         *      从主机名和端口号创建套接字地址。
         */
        //InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 10000);
        InetSocketAddress inetSocketAddress = new InetSocketAddress(InetAddress.getByName("www.baidu.com"), 10000);

        /**
         * String getHostName()
         *      获得 hostname 。
         */
        System.out.println(inetSocketAddress.getHostName()); //www.baidu.com
        /**
         * String getHostString()
         *      如果没有主机名(使用文字创建),则返回主机名或地址的String形式。
         */
        System.out.println(inetSocketAddress.getHostString()); //www.baidu.com
        /**
         * int getPort()
         *      获取端口号。
         */
        System.out.println(inetSocketAddress.getPort()); //10000
        /**
         * InetAddress getAddress()
         *      获得 InetAddress 。
         */
        System.out.println(inetSocketAddress.getAddress()); // www.baidu.com/180.101.49.12
    }

3. 协议 (protocol)

       协议(Protocol):网络协议的简称,是对数据格式和计算机之间交换数据时必须遵守的规则的正式描述。

在www上,每一信息资源都有统一且唯一的地址,即统一资源定位符。Uniform Resource Locator,简称URL,      如:https://localhost:8080/index.html ,有4部分组成。(协议,主机域名或IP,端口号,资源文件名)

     网络三大基石:HTML,HTTP,URL

     URI = URL+URN

     URI:Uniform Resource Identifier ,统一资源标志符。

     URL:Uniform Resource Locator,统一资源定位符。

     URN:Uniform Resource Name,统一资源命名。

     在Java中,使用 java.net.URL  类来表示URL

3、URLEncoder编码和URLDecoder解码 

ULRDecoder和URLEncoder的主要作用是实现:普通字符串和application/x-www-form-urlencoded字符串相互转换的功能。

为什么会有这种转换呢?

网页的 URL 规定只能包含合法的字符,这可以分成两类。

URL 元字符:分号(;),逗号(’,’),斜杠(/),问号(?),冒号(:),at(@),&,等号(=),                加号(+),美元符号($),井号(#)

语义字符:a-z,A-Z,0-9,连词号(-),下划线(_),点(.),感叹号(!),波浪线(~),星号(*),单引号(‘),圆括号(())

除了以上字符,其他字符出现在 URL 之中都必须转义,规则是根据操作系统的默认编码,将每个字节转为百分号(%)加上两个大写的十六进制字母。比如,UTF-8 的操作系统上,

      

简单说一下乱码的场景和简单转换时的执行原理:

       首先,form表单提示数据时,默认Content-type:为 application/x-www-form-urlencoded,当然也可以是:multipart/form-data ,multipart/form-data 一般用做form表单以流的形式提交数据时,则设置,enctype为该form-data形式,

       不过呢,一般情况下,提交方式为application/x-www-form-urlencoded MIME编码, 当环境等等都已经配置为统一编码后,仍然出现汉字传到后台 被解码处理的情况时(也就是所谓的乱码 ),此时可以尝试,使用URLDecoder进行解码再转换,然后转换为汉字,当然在使用场景上,其实还是有很多情况下需要区分的。

       

      普通字符串和application/x-www-form-urlencoded MIME类型字符串之间的相互转换。

    public static void main(String[] args) throws IOException {
        //获取平台默认的字符集
        System.out.println(System.getProperty("file.encoding")); //UTF-8
        String msg = "宝塔镇河妖abc";

        //使用UTF-8编码
        String msg1 = URLEncoder.encode(msg,"UTF-8");
        System.out.println(msg1);//%E5%AE%9D%E5%A1%94%E9%95%87%E6%B2%B3%E5%A6%96abc
        //使用UTF-8解码
        String msg2 = URLDecoder.decode(msg1,"UTF-8");
        System.out.println(msg2);//宝塔镇河妖abc       
    }

4、URL类和URLConnection类

1. URL类

在 java.net 包中包含专门用来处理 URL 的 URL类,可以获得 URL 的相关信息。

URL 的构造方法和常用方法:

 

    //方法等具体查看API
    public static void main(String[] args) throws IOException {
        URL url = new URL("https://www.baidu.com");
        
        //获取此的授权部分 URL 。
        System.out.println(url.getAuthority());
        //获取此 URL的文件名。
        System.out.println(url.getFile());
        //获取端口
        System.out.println(url.getPort());
        //获取主机
        System.out.println(url.getHost());
        //获得默认端口
        System.out.println(url.getDefaultPort());
        //获得路径
        System.out.println(url.getPath());
        //获取该 URL的userInfo部分。
        System.out.println(url.getUserInfo());
    }

2. URLConnection 类

在 java.net 包中,定义了专门的 URLConnection 类来表示与 URL 建立的通信连接。

URLConnection 类的对象使用 URL 类的 openConnection() 方法获得。

注意:我们在应用程序和URL链接的时候,使用URLConnection类。

          当我们HTTP和URL连接的时候,使用URLConnection类的子类HttpURLConnection。

URLConnection 类的主要方法:

 

三、基于Socket的java网络编程

        网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。

       一个Socket由一个IP地址和一个端口号唯一确定。

       Socket编程通信主要涉及到客户端和服务器端两个方面,首先是在服务器端创建一个服务器套接字(ServerSocket),并把它附加到一个端口上,服务器从这个端口监听连接。

       客户端请求与服务器进行连接的时候,根据服务器的域名或者IP地址,加上端口号,打开一个套接字。当服务器接受连接后,服务器和客户端之间的通信就像输入输出流一样进行操作。

       

      在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程

1、简单的Client/Server程序 

     需求: 客户端连接服务端时,服务端向客户端发送消息

public class Server {
    public static void main(String[] args) throws IOException {
        // 1、创建服务器,指定端口 ServerSocket(int port)
        ServerSocket serverSocket = new ServerSocket(10001);
        // 2、接受连接该服务端的客户端对象,阻塞式
        Socket client = serverSocket.accept();
        System.out.println("一个客户端建立连接,IP:" + client.getInetAddress());

        // 3、IO 操作
        // 获取到客户端的输出流对象给客户端输出数据
        boolean accept = true;
        while (accept) {
            String data = "服务器-->:" + client.getInetAddress() + "你来了";
            PrintStream out = new PrintStream(client.getOutputStream());
            out.print(data);
            out.close();
        }

        // 4、关闭此套接字。
        //serverSocket.close();
    }
}
public class Client {
    public static void main(String[] args) throws IOException {
        // 1、创建客户端必须指定服务器的IP+端口,此时就在连接
        Socket client = new Socket("127.0.0.1",10001);

        // 2、IO操作,自动关闭流
        // 获取客户端的输入流对象
        Scanner sc = new Scanner(client.getInputStream());
        while (sc.hasNextLine()) {
            String str = sc.nextLine();
            System.out.println(str);
        }
        sc.close();

        // 3、关闭此套接字。
        client.close();
    }
}

 


 

参考文章:

Java - 网络编程完全总结

成为高手前必懂的TCP干货

计算机网络漫谈:OSI七层模型与TCP/IP四层(参考)模型

一文搞懂TCP与UDP的区别

Java Socket示例 发文件

      

ends~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值