Java网络编程

计算机网络

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

通信协议

虽然通过及赛季网络可以实现多喝计算机的连接,但是位于同一个网络中的计算机在通信时必须遵循一定的协议。计算机网络中,实现连接和通信的规则被称为网络协议,它对数据传输格式,传输速率,传输步骤作了同一规定,通讯双方必须遵守规则才能完成数据交换。

在这里插入图片描述
● 链路层:链路层是用于定义物理传输通道,通常是对某些网络连接设备的驱动协议,例如针对光纤、双绞线提供的驱动。

● 网络层:网络层是整个TCP/IP协议的核心,它主要用于将传输的数据进行分组,将分组数据发送到目标计算机或者网络。

● 运输层:主要使网络程序进行通信,在进行网络通信时,可以采用TCP协议,也可以采用UDP协议。

● 应用层:主要为互联网中的各种网络应用提供服务。

IP和端口号

计算机网络中每个电脑都有唯一的标识符即IP,通过IP来指定接收数据的计算机或发送数据的计算机。IP广泛使用的版本时IPv4,他是有4个字节的二进制表示00001000001000010000000000000001,二进制表示IP不便于记忆和处理,使用点分十进制计法每个字节用一个十进制表示并用.隔开127.0.0.1

IPv4共分为5类,其中常用的有三类:
A类地址:由第一段的网络和其余三段的主机地址组成,范围1.0.0.0-127.255.255.255
B类地址:由前两段的网络地址和其余两段的主机地址组成,范围128.0.0.0-191.255.255.255
C类地址:由前三段的网络地址和最后一段的主机地址组成,范围192.0.0.0-223.255.255.255

通过IP地址可以连接到指定的计算机,通过端口号可以访问目标计算机的某个应用程序。端口号是两个字节表示的,其范围为0-2^16-1。其中0-1023由操作系统的网络服务占用,用户的普通应用占用1024以上的端口号。
在这里插入图片描述

InetAddress

JDK中提供了一个与IP地址相关的InetAddress类,提供了一系列与IP地址相关的方法。都在java.net下。

InetAddress的创建在这里插入图片描述
InetAddress类最重要的就是获取主机名和IP地址了,有两种主要的方式创建InetAddress类:通过主机名或域名创建getByName(),通过本地创建getLocalhost()

import java.net.InetAddress;
/*
	...
*/
InetAddress inetAddress=InetAddress.getLocalHost(); //本地获取
InetAddress inetAddress1=InetAddress.getByName("www.baidu.com");  //域名获取
      

InetAddress API
InetAddress类提供一些列IP地址相关的方法,其中最主要的有两个inetAddress.getHostName()用于获取域名,inetAddress.getHostAddress()获取IP地址。

package com.company.ipaddress;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class Ipaddr {

    public static void main(String[] args) throws UnknownHostException {
        InetAddress inetAddress=InetAddress.getLocalHost();
        InetAddress inetAddress1=InetAddress.getByName("www.baidu.com");
        System.out.println("主机名:"+inetAddress.getHostName());
        System.out.println("IP地址:"+inetAddress.getHostAddress());
        System.out.println("-----------------");
        System.out.println("主机名:"+inetAddress1.getHostName());
        System.out.println("主机IP:"+inetAddress1.getHostAddress());

    }
}

在这里插入图片描述

UDP与TCP协议

UDP与TCP协议是传输层的两个协议,UDP是用户数据报协议,TCP是传输控制协议。

UDP协议是无连接,无状态协议,发送时不会确认接收端是否存在,接收端在接收后也不会反馈是否接收到数据。因此UDP协议消耗资源少,常用于音频,视频的传输。

TCP协议是面向连接的协议。在传输前先建立发送端与接收端的逻辑连接,提供了无差错的数据传输。每次创建连接都要经过三次握手。第一次握手,客户端向服务器发送连接请求,等待服务器确认;第二次握手,服务器向客户端发送一个相应连接的请求;第三次握手,客户端向服务器发送连接确认请求,确认连接。
在这里插入图片描述

UDP通信

TCP/IP各层传输的基本单元。
在这里插入图片描述

JDK提供了DatagramPacket类用于封装发送或接收的数据。atagramPacket类就相当于一个工厂,将数据封装为传输层的基本传输单元报文段,通过IP和端口号(套接字)发送到对应的应用程序。

DatagramPacket

DatagramPacket提供了一下构造方法:
DatagramPacket(byte[] buf, int length)
该构造方法用于接收端创建DatagramPacket时指定数据的字节数组和数组的长度大小。

DatagramPacket(byte[] buf, int offset, int length)
用于接收端创建DatagramPacket时指定数据的字节数组和数组的长度大小,字节数据从offset处开始。

DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
用于发送端,指定了字节数组的大小和长度,字节数据从offset处开始。并指定了接收端的IP和端口。

DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)
用于发送端,指定了字节数组的大小和长度,并指定了接收端的套接字。

DatagramPacket(byte[] buf, int length, InetAddress address, int port)
用于发送端,指定了字节数组的大小和长度,字节数据从offset处开始。并指定了接收端的IP和端口。

DatagramPacket(byte[] buf, int length, SocketAddress address)略。

在这里插入图片描述

DatagramSocket

DatagramPacket用于将数据打包,但光打包并不能实现数据通信,还需要这种特定报文段数据的接收装置,即DatagramSocket,该类主要用于对报文端的发送与接收。

DatagramSocket提供如下构造方法:
DatagramSocket()随机发送一个没有被其他网络应用占有的端口。
DatagramSocket(int port)监听指定的端口

DatagramSocket(int port,InetAddress addr)指定数据从哪个端口和哪个网卡发送和接收数据。

在这里插入图片描述

package com.company.udp;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.apache.commons.io.IOUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;

public class UdpTest {
    public static void main(String[] args) {
        new SendData().start();
        new ReceiveData().start();
    }



}

class ReceiveData extends Thread{
    @Override
    public void run() {
        try {
            //定义字节数组用于接收数据
            byte[] bytes=new byte[1024];
            //监听接收数据
            DatagramSocket datagramSocket=new DatagramSocket(9000);
            //接收报文端
            DatagramPacket datagramPacket=new DatagramPacket(bytes,bytes.length);
            System.out.println("等待接收数据...");
            //解析获取的数据
            bytes=datagramPacket.getData();
            System.out.println("正在解析数据...");
            System.out.println(bytes);
            datagramSocket.close();
            System.out.println("接收完毕...");

        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

class SendData extends Thread{
    @Override
    public void run() {
        try {
            DatagramSocket datagramSocket=new DatagramSocket(3000);
            String params="Hello World";
            byte[] bytes=params.getBytes();
            System.out.println("正在封装数据...");
            DatagramPacket datagramPacket=new DatagramPacket(bytes,bytes.length, InetAddress.getByName("localhost"),9000);
            System.out.println("正在发送数据...");
            datagramSocket.send(datagramPacket);
            datagramSocket.close();
            System.out.println("发送完毕...");
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

在这里插入图片描述

TCP通信

UDP与TCP通信的区别在于,UDP只有发送端和接收端,计算机之间可以任意发送数据。而TCP通信时严格区分客户端和服务器端的,在通信时必须由客户机去连接服务器才能实现通信,服务器不可以主动去连接客户端,并且服务端程序必须事先启动,等待客户端连接。

JDK中提供了两个用于实现TCP程序的类,一个是ServerSocket类表示服务器端;一个是Socket类表示客户端。通讯时首先创建服务器端的ServerSocket对象开启一个服务,等待客户端连接。让后创建Socket对象开启客户端,向服务端发送请求,经过三次握手后,建立连接,开启通信。
在这里插入图片描述

ServerSocket

TCP服务需要先创建服务器应用程序,JDK的java.net包下提供ServerSocket类,实例化该对象即可实现TCP程序,构造方法实例化ServerSocket对象。

serverSokcet构造方法

ServerSocket()
该构造方法没有绑定端口,不能直接通信,需要调用bind(SocketAddress endpoint)绑定端口才可以使用。

ServerSocket(int port)
使用该构造方法绑定一个端口,实现服务器的监听。

ServerSocket(int port,int backlog)
该构造方法增加了一个backlog参数用于指定在服务器繁忙时可以继续与服务器通讯的数量,默认为50。

ServerSocket(int port,int backlog,InetAddress bind Addr)
该构造方法又绑定了InetAddress对象即IP对象,用于指定相关的ip地址,适用于电脑多个网卡和多个ip的情况。

ServerSocket常用方法
在这里插入图片描述
ServerSocket负责鉴定计算机的端口号,创建ServerSocket对象后需要调用accept()方法,是进程处理堵塞状态,等待客户机发送的请求,aceept()方法才会返回一个Scoket对象。用于和客户机通讯,程序继续进行。

Socket

客户端程序Socket,服务端需要等待客户端的请求。JKD提供了Socket类创建客户端程序,提供了多种构造方法。

Socket构造方法

Socket()
构造方法创建Socket对象没有指定ip地址和端口号,是无法连接到服务器的,还需要调用对象的connect(SocketAddress endpoint)方法指定ip地址和端口号。该方法用于封装ip和端口号即套接字

Socket(String host,int port)
构造方法根据参数配置的ip和端口号去连接运行的服务器程序。

Socket(InetAddress,int port)
该构造方法传入的参数一个InetAddress类封装了IP的相关信息,程序也会根据参数信息去连接执行服务器程序。

Socket常用方法
在这里插入图片描述

TCP程序

服务端ServerSocket程序:

public class Server {
    public static void main(String[] args) throws IOException {
        OutputStream outputStream;
        InputStream inputStream = null;

            //创建服务器
            ServerSocket serverSocket = new ServerSocket(9000);
            System.out.println("服务器创建成功...");

         do{
             //启动服务器
             System.out.println("服务器已启动...");
             Socket socket = serverSocket.accept();

            //监听客户端
            outputStream = socket.getOutputStream();
            System.out.println("TCP服务连接成功...");
            outputStream.write("连接成功----welcome!".getBytes(StandardCharsets.UTF_8));

             //获取客户端数据
             inputStream = socket.getInputStream();
            System.out.println(inputStream.toString());
            inputStream=null;
        }while(inputStream ==null);


    }
}

客户端Socket程序:

public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(InetAddress.getLocalHost(), 9000);

        System.out.println("正在连接到服务器...");
        //读取服务器端响应数据判断是否连接
        InputStream inputStream = socket.getInputStream();
        System.out.println("接收到服务器端数据:"+inputStream.toString());

        boolean flag=false;
        do {
            //向服务端发送数据
            System.out.println("请输入-----enter发送...");
            Scanner scanner = new Scanner(System.in);
            String parma = scanner.nextLine();
            byte[] bytes = parma.getBytes();
            OutputStream outputStream=socket.getOutputStream();
            outputStream.write(bytes);

            }
        while (flag);

            //是否继续发送
            System.out.println("继续发送请输入:  1");
            Scanner sc=new Scanner(System.in);
            int lock=sc.nextInt();
            if(lock==1){
                flag=true;
            }
        }
}

启动程序:
在这里插入图片描述
在这里插入图片描述

TCP协议是传输层协议,作用是解决如何在网络中传输数据的问题,如将书发送到某个网络或主机上。但是对于接收放又出现了一个新的问题?这些数据给谁用,数据的内容是什么。可见光有TCP协议传输的数据并没有意义。

要使数据有意义,必须使用应用层协议,常见的应用层协议有HTTP,FTP等。WEB使用HTTP协议封装文本信息,在使用TCP协议将器发送到网络上。

HTTP与TCP协议

Java发送http协议最实用的就是Servlet,继承Servlet或HttpServlet。Servlet

TCP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。

TCP/IP和HTTP协议的关系,从本质上来说,二者没有可比性,我们在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到应用层协议,应用层协议有很多,比如HTTP、FTP、TELNET等,也可以自己定义应用层协议。WEB使用HTTP协议作应用层协议,以封装HTTP 文本信息,然后使用TCP/IP做传输层协议将它发到网络上。

Http协议是建立在TCP协议基础之上的,当浏览器需要从服务器获取网页数据的时候,会发出一次Http请求。Http会通过TCP建立起一个到服务器的连接通道,当本次请求需要的数据完毕后,Http会立即将TCP连接断开,这个过程是很短的,所以Http连接是一种短连接,是一种无状态的连接。所谓的无状态,是指浏览器每次向服务器发起请求的时候,不是通过一个连接,而是每次都建立一个新的连接。如果是一个连接的话,服务器进程中就能保持住这个连接并且在内存中记住一些信息状态。而每次请求结束后,连接就关闭,相关的内容就释放了,所以记不住任何状态,称为无状态连接。而我们直接通过Socket编程使用TCP协议的时候,因为我们自己可以通过代码区控制什么时候打开连接什么时候关闭连接,只要我们不通过代码把连接关闭,这个连接就会在客户端和服务端的进程中一直存在,相关状态数据会一直保存着。

形象的描述:HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。对于从C#编程的角度来讲,为了方便,你可以直接选择已经制造好的轿车Http来与服务器交互。但是有时候往往因为环境因素或者其他的一些定制的请求,必须要使用TCP协议,这时就需要使用Socket编程,然后自己去处理获取的数据。就像是你用已有的发动机,自己造了一辆卡车,去从服务器交互。

HTTP(超文本传输协议)是利用TCP在两台电脑(通常是Web服务器和客户端)之间传输信息的协议。客户端使用Web浏览器发起HTTP请求给Web服务器,Web服务器发送被请求的信息给客户端。

HTTP连接举例:

我们模拟一下TCP短连接的情况,client向server发起连接请求,server接到请求,然后双方建立连接。client向server发送消息,server回应client,然后一次读写就完成了,这时候双方任何一个都可以发起close操作,不过一般都是client先发起 close操作。为什么呢,一般的server不会回复完client后立即关闭连接的,当然不排除有特殊的情况。

从上面的描述看,短连接一般只会在 client/server间传递一次读写操作。
短连接的操作步骤是:建立连接——数据传输——关闭连接…建立连接——数据传输——关闭连接

1、HTTP协议的几个重要概念
1.连接(Connection):一个传输层的实际环流,它是建立在两个相互通讯的应用程序之间。
2.消息(Message):HTTP通讯的基本单位,包括一个结构化的八元组序列并通过连接传输。
3.请求(Request):一个从客户端到服务器的请求信息包括应用于资源的方法、资源的标识符和协议的版本号
4.响应(Response):一个从服务器返回的信息包括HTTP协议的版本号、请求的状态(例如“成功”或“没找到”)和文档的MIME类型。
5.资源(Resource):由URI标识的网络数据对象或服务。
6.实体(Entity):数据资源或来自服务资源的回映的一种特殊表示方法,它可能被包围在一个请求或响应信息中。一个实体包括实体头信息和实体的本身内容。
7.客户机(Client):一个为发送请求目的而建立连接的应用程序。
8.用户代理(Useragent):初始化一个请求的客户机。它们是浏览器、编辑器或其它用户工具。
9.服务器(Server):一个接受连接并对请求返回信息的应用程序。
10.源服务器(Originserver):是一个给定资源可以在其上驻留或被创建的服务器。
11.代理(Proxy):一个中间程序,它可以充当一个服务器,也可以充当一个客户机,为其它客户机建立请求。请求是通过可能的翻译在内部或经过传递到其它的服务器中。一个代理在发送请求信息之前,必须解释并且如果可能重写它。
代理经常作为通过防火墙的客户机端的门户,代理还可以作为一个帮助应用来通过协议处理没有被用户代理完成的请求。
12.网关(Gateway):一个作为其它服务器中间媒介的服务器。与代理不同的是,网关接受请求就好象对被请求的资源来说它就是源服务器;发出请求的客户机并没有意识到它在同网关打交道。
网关经常作为通过防火墙的服务器端的门户,网关还可以作为一个协议翻译器以便存取那些存储在非HTTP系统中的资源。
13.通道(Tunnel):是作为两个连接中继的中介程序。一旦激活,通道便被认为不属于HTTP通讯,尽管通道可能是被一个HTTP请求初始化的。当被中继的连接两端关闭时,通道便消失。当一个门户(Portal)必须存在或中介(Intermediary)不能解释中继的通讯时通道被经常使用。
14.缓存(Cache):反应信息的局域存储。

2、 http请求由三部分组成,分别是:请求行、消息报头、请求正文

1、请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下:Method Request-URI HTTP-Version CRLF
其中 Method表示请求方法;Request-URI是一个统一资源标识符;HTTP-Version表示请求的HTTP协议版本;CRLF表示回车和换行(除了作为结尾的CRLF外,不允许出现单独的CR或LF字符)。

请求方法(所有方法全为大写)有多种,各个方法的解释如下:
GET 请求获取Request-URI所标识的资源
POST 在Request-URI所标识的资源后附加新的数据
HEAD 请求获取由Request-URI所标识的资源的响应消息报头
PUT 请求服务器存储一个资源,并用Request-URI作为其标识
DELETE 请求服务器删除Request-URI所标识的资源
TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断
CONNECT 保留将来使用
OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求
应用举例:
GET方法:在浏览器的地址栏中输入网址的方式访问网页时,浏览器采用GET方法向服务器获取资源,eg:GET /form.html HTTP/1.1 (CRLF)

POST方法要求被请求服务器接受附在请求后面的数据,常用于提交表单。
eg:POST /reg.jsp HTTP/ (CRLF)
Accept:image/gif,image/x-xbit,… (CRLF)…HOST:www.guet.edu.cn (CRLF)
Content-Length:22 (CRLF)
Connection:Keep-Alive (CRLF)
Cache-Control:no-cache (CRLF)
(CRLF) //该CRLF表示消息报头已经结束,在此之前为消息报头
user=jeffrey&pwd=1234 //此行以下为提交的数据

HEAD方法与GET方法几乎是一样的,对于HEAD请求的回应部分来说,它的HTTP头部中包含的信息与通过GET请求所得到的信息是相同的。利用这个方法,不必传输整个资源内容,就可以得到Request-URI所标识的资源的信息。该方法常用于测试超链接的有效性,是否可以访问,以及最近是否更新。
2、请求报头后述
3、请求正文()

3、HTTP响应也是由三个部分组成,分别是:状态行、消息报头、响应正文
1、状态行格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF
其中,HTTP-Version表示服务器HTTP协议的版本;Status-Code表示服务器发回的响应状态代码;Reason-Phrase表示状态代码的文本描述。
状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
1xx:指示信息–表示请求已接收,继续处理
2xx:成功–表示请求已被成功接收、理解、接受
3xx:重定向–要完成请求必须进行更进一步的操作
4xx:客户端错误–请求有语法错误或请求无法实现
5xx:服务器端错误–服务器未能实现合法的请求
常见状态代码、状态描述、说明:
200 OK //客户端请求成功
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
eg:HTTP/1.1 200 OK (CRLF)

2、响应报头后述

3、响应正文就是服务器返回的资源的内容

4.关闭连接
客户和服务器双方都可以通过关闭套接字来结束TCP/IP对。

转载自HTTP协议 与 TCP协议 的区别谢谢作者@梦在明天

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xvwen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值