网络编程基础、网络通信三要素、TCP通信、Socket类

网络编程基础

软件架构:
  • C/S架构: 即Client/Server(客户端/服务器端)架构,QQ、迅雷。

  • B/S架构: 即Browser/Server(浏览器端/服务器端)架构,简化了系统的开发,维护和使用。谷歌、火狐。

B/S架构与C/S架构的区别:

  • C/S架构基于局域网的,而B/S架构基于广域网的基础上。

  • 硬件环境不同,C/S建立在专用网络上,小范围的网络,可以专门的服务器提供数据连接和数据交换

  • C/S一般面向的固定用户群体,对信息的安全控制较高较高一点。

  • 对程序架构不同

  • 用户接口不同:C/S架构大多建立在Windows平台上,B/S建立在浏览器上,不仅可以应用在Windows平台上,也可以应用在Unix/Linux等平台上。

两种架构各有优劣,但是无论使用哪种架构,都离不开网络的支持。网络编程,就是在一定的协议下,实现两台计算机通信的程序。

网络通信协议

  • 网络通信协议:通信协议是计算机通信必须遵从的一种规则,协议中对数据的传输格式、传输的速率、传输的步骤等都做了统一的规定,通信双方必须同时遵守,最终实现数据的正常传输和交换。

  • TCP/IP:传输控制协议(TCP)/因特网互联协议(IP),他们俩定义了计算机如何联网、数据如何交换和传输的标准。它的内部包含了一系列用于处理数据通信的协议,并采用了4层的分层模型,每一层都呼叫下一层所提供的协议来完成自己的请求。

网络编程基础、网络通信三要素、TCP通信、Socket类

协议分类

  • TCP协议:传输控制协议,该协议是面向连接的通信协议,即数据传输前,在发送端和接收端先建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠的无差错的数据传输。

    • 三次握手:在数据发送的准备阶段,客户端和服务器之间通过三次交互,保证连接的可靠性。

      三次握手:

网络编程基础、网络通信三要素、TCP通信、Socket类

通过三次握手,建立连接后,客户端和服务器端就可以进行数据传输了。由于这种面相连接的特性,TCP协议能够数据传输的安全。所以应用挺广泛的,下载文件等。

  • ​ UDP:用户数据报协议(User DataProgram Protocal),他是一个面相无连接的协议。在进行数据传输时,不需要建立连接。不管对方在不在,直接将数据、数据源和目的地封装到数据包中,发送过去。每次发送的数据不能很大,限制在64K以内,数据有可能丢失,数据传输时不安全,速度快,QQ聊天

网络编程三要素【了解】

  • 协议:计算机通信必须遵守的规则。

  • IP地址:互联网协议地址,俗称IP,IP地址用来给网络中的计算机编订一个唯一的编号。

  • 端口号:端口号就是唯一标识设备中的进程(应用程序)。IP地址是唯一标识网络中的设备。

  • IP地址:互联网协议地址(Internet Protocol Address) ,俗称IP,给网络中的计算机设备编订一个唯一的编号,好比人的身份证号。

    IP地址分类:

    • IPv4:是一个32位的二进制数,通常被分为4个字节,表示形式:a.b.c.d ,例如:192.168.53.245 ,其中a.b.c.d都是一个0~255之间的十进制的整数,那么最多能够表示42亿个。

    • IPv6:为了扩大地址空间,通过IPv6重新定义地址空间,采用128位地址长度,每16个字节分为一组,分成8组十六进制数 ,表示形式:ABCD:EF01:2345:6789:ABCD:EF01:2345:6789,号称互联网中的任何一粒沙子能够编写进去,解决了地址不够的问题。

  通过DOS命名查看本机的IP地址:ipconfig

  检查网络连接是否正常:ping ip地址

特殊的IP地址:

  本机的IP地址:127.0.0.1 localhost 通过hosts文件,可以自定义自己的域名

  • 端口号:如何区分在网络通信中打开的这些进程(应用程序)?通过端口号可以准确的找到彼此。

  • 端口号:用两个字节表示的整数,它的取值范围是0~65535。 其中,0~1023之间的的端口号被一些知名的应用和网络服务占用了。普通的常规的应用程序只能使用从1024以上的端口号, 如果端口号被另外一个服务或者应用程序占用了,会导致当前程序启动失败。

  常用的端口号:

   Tomcat应用服务器:8080

   HTTP服务器:80 www.baidu.com:80 80端口可以选择省略不写

   数据库服务器:MYSQL:3306 Oracle:1521

TCP通信

目的:实现两台计算机之间的交互,通信两端要严格区分客户端和服务器端口

两端通信的步骤:

  1. 服务端需要启动,等待客户端链接

  2. 客户端需要主动地链接服务器端,链接成功才能通信,服务器端口不可以主动链接客户端

在java中,提供两个类,实现TCP通信:

  • 客户端:创建Socket对象,创建之后就相当于创建了客户端,向服务器端发送链接请求,服务器端回响一个请求表示已经接受,两者就建立了通信

  • 服务器端:创建ServerSocket对象,创建之后就相当于,开启了一个服务,等待客户端链接

Socket类

Socket类,实现客户端套接字,套接字指的是两台设备之间通讯的端点,

构造方法:

public Socket(String host,int port);--->创建套接字对象并连接到指定主机的指定端口号,如果指定了host是一个null,那么就相当于与指定地址为回送地址【127.x.x.x】,是本机的回送地址,主要用于网络软件测试使用,本机上进程间的通信。就不会进行网络传输

成员方法:

  • public InputStream getInputStream();---->获取套接字的输入流

  • public OutputStream getOutputStream();--->获取套接字输出流

  • public void close();--->关闭套接字

  • public void shoutdownOutput();--->禁用套接字输出流

  • 任何先前写入的数据都将会被发送,最后终止输出流

ServerSocket类

ServerSocket类实现了服务器端套接字,该对象等待通过网络的请求

构造方法:

ServerSocket(int port);--->使用该构造方法子创建ServerSocket创建对象时,就可以将其绑定到一个指定的端口号上面,参数port就是端口号

成员方法:

public Socket accept();--->监听并接受连接,返回一个新的Socket对象,用于和用户端实现通信。

文件上传案例:

步骤:

  1. 在客户端当中,通过输入流,从硬盘当中读取文件数据到内存

  2. 在客户端当中,通过输出流,写入文件数据到服务器端

  3. 在服务器端中,通过输入流,读取文件数据到服务器端中

  4. 在服务器端中,通过输出流,写入文件数据到服务器硬盘当中

文件上传图解:

网络编程基础、网络通信三要素、TCP通信、Socket类

文件上传优化

文件的名称需要优化

服务端,保存文件的名称如果名称固定,那么最终会导致服务器硬盘,只会保留一个文件,对上传的文件名称优化,

//文件名称定义规则:
"beautiful" + System.currentTimeMillis() + new Random().nextInt(1000000) + ".jpg";
服务器端接收文件的优化

服务器端,接收一个文件之后就关闭了,后面的其他客户端无法继续上传文件,使用循环进行改进,可以不断的接收不同的客户端传输过来的文件。

// 使用循环
while(true) {
   Socket socket =  serverSocket.accept(); 
   ....
   ....       
}
服务器端接收客户端文件的效率的优化

服务器端,在接收文件的时候,加入某个客户端给你传输一个大文件,此时就不能再接收其他用户的文件,所以可以用多线程技术优化接收效率。

while(true) {
      Socket socket = serverSocket.accept();
      // 使用多线程技术,提高程序的效率
      // 有一个客户端上传文件,就开启一个线程,完成文件的上传
     new Thread(new Runnable() {
         // 重写run方法,设定线程的任务
         @Override
         public void run() {
             // 使用网络字节输入流对象
            InputStream is =  socket.getInputStream();
            // 指定一个目录
           File file =  new File("D:\upload");
             if(!file.exits()) {
                 file.mkdirs();
             }
             // 防止同名的文件被覆盖
         String filename =  "beautiful" + System.currentTimeMillis() + new Random().nextInt(1000000) + ".jpg";  
           // 构建一个本地的文件字节输出流对象
             new FileOutputStream(file + "\" + filename);
           // 一读一写完成文件的上传,最终把文件写入到服务器端的硬盘当中。  
          .....  
         }
     }).start();
}
// 服务端不关闭
// serverSocket.close();