JAVA-网络编程应用实例

网络编程三要素

协议

网络通信协议

IP地址

在网络中用许多计算机,IP地址作为计算机的唯一标识。

端口

每个软件对应的标识。两个字节表示。范围在0-65535之间。前1024一般不用,已经指定给其他的软件。


TCP通信步骤

  1. 服务器先启动
  2. 服务器不会主动请求客户端,必须使用客户端请求服务器端。
  3. 客户端与服务器端建立连接后,在连接中会创建一个IO对象
  4. 客户端与服务端就可以通过这个IO对象来进行通信
  5. 通信的数据不仅仅是字符,所以创建的IO对象是字节流对象。

服务器端必须明确两件事

  1. 多个客户端和服务器进行交互时,服务器要知道是哪个客户端和自己交互。所以在服务器端提供了一个acceot()方法获取到客户端请求的对象。
  2. 多个客户端跟服务器端进行交流时,就要使用多个IO流对象。但是在服务器端并没有IO对象,而是使用客户端的流对象。

TCP通信示例-java

/*
tcp通信客户端:向服务器端发送请求,给服务器发送数据,读取服务器回写的数据
表示客户端的对象:java.net中Socket对象;此类对象实现了客户端套接字。套接字中应包含服务器的IP地址值与端口号
构造方法:Socket(String host, int port)  创建流套接字并将其连接到指定主机上的指定端口号。
参数:String host 服务器主机的名称/IP地址 
     int port  服务器的端口号
成员方法:InputStream  getInputStream()  返回此套接字的输入流。
       OutputStream  getOutputStream() 返回此套接字的输出流。
       void close() 释放资源
实现步骤:
1.创建一个客户端对象Socket,构造方法绑定服务器的IP地址和端口号。
2.使用成员方法对象getOutputStream()获取网络字节输出流对象OutputStream
3.使用OutputStream对象中方法write()方法向服务器端发送数据。
4.使用成员方法对象getInputStream() 获取网络字节输入流对象InputStream
5.使用InputStream对象中方法read()方法读取数据。
6.释放资源(Socket.close)
注意:
1.客户端与服务端在进行交互时,只能使用Socket中提供的网络流,服务器端不能创建自己的流对象
2.当我们创建客户端对象Socket时,就会请求服务器并且和服务器建立3次握手后建立连接通路。如果服务器没有正常启动,那么就会抛出异常。
如果服务器已经启动,那么连接成功,可以进行交互。

*/

package 网络通信;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class TCPClient {
    public static void main(String[] args) throws IOException {
        //创建一个客户端对象Socket
        Socket client=new Socket("127.0.0.1",8888);
        //使用成员方法对象getOutputStream​()获取网络字节输出流对象OutputStream
        OutputStream os = client.getOutputStream();
        os.write("你好服务器".getBytes());
        //使用成员方法对象getInputStream​() 获取网络字节输入流对象InputStream
        InputStream input = client.getInputStream();
        //使用InputStream对象中方法read()方法读取数据。
        byte[] bytes=new byte[1024];
        int len=input.read(bytes);
        System.out.println(new String(bytes,0,len));
        //6.释放资源(Socket)
        client.close();
    }
}
-------------------------------------------------------
//服务器端
/*
服务器端:接收客户端的请求;接受客户端的数据;向客户端回写数据
ServerSocket  这个类实现了服务器套接字

构造方法:ServerSocket(int port) 创建绑定到指定端口的服务器套接字。
服务器端必须明确一件事情,必须找到那个客户端在请求它。使用accept()方法。
成员方法:Socket accept() 侦听要连接到此套接字并接受它 ,返回值为Socket对象。

服务器实现步骤:
1.创建服务器Server对象和系统要指定的端口号。
2.使用成员方法accept(),获取到请求的客户端。
3.使用成员方法对象getInputStream() 获取网络字节输入流对象InputStream
4.使用InputStream对象中方法read()方法读取客户端数据。
5.使用成员方法对象getOutputStream()获取网络字节输出流对象OutputStream
6.使用OutputStream对象中方法write()方法向客户端回送数据。
7.释放资源(Socket,ServerSocket)
*/
package 网络通信;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer {
    public static void main(String[] args) throws IOException {
        //1.创建服务器Server对象和系统要指定的端口号。
        ServerSocket Server=new ServerSocket(8888);
        //2.使用成员方法accept(),获取到请求的客户端。
        Socket so = Server.accept();
        //3.使用成员方法对象getInputStream​() 获取网络字节输入流对象InputStream
        InputStream input = so.getInputStream();
        //4.使用InputStream对象中方法read()方法读取客户端数据。
        byte[] bytes=new byte[1024];
        int len=input.read(bytes);
        System.out.println(new String(bytes,0,len));
        //5.使用成员方法对象getOutputStream()获取网络字节输出流对象OutputStream
        OutputStream output = so.getOutputStream();
        //6.使用OutputStream对象中方法write()方法向客户端回送数据。
        output.write("谢谢收到".getBytes());
        //7.释放资源(Socket,ServerSocket)
        so.close();
        Server.close();
    }

}


TCP文件上传案例

原理:客户端从本地上传读取文件,把文件上传到服务器,服务器把上传的文件保存到服务器的硬盘上。

步骤分析

  1. 客户端使用本地字节输入流读取上传的文件
  2. 客户端使用网络字节输出流,把读取到文件上传到服务器
  3. 服务器端使用网络输入流对象,读取客户端上传的文件
  4. 服务器端创建本地输出流,将文件存储到服务器本地文件
  5. 服务器使用网络字节输出流,给客户端会送一个“上传成功”
  6. 客户端使用网络字节输入流,读取服务器写的数据。

注意:客户端和服务器端在本地对硬盘读取与存入时,需要使用自己创建的输入、输出流:客户端与服务器端在进行网络通信时,必须使用Socket对象中输入、输出流。

文件的上传原理:是对文件的复制;必须明确 数据源 数据的目的地。

-----------------------------------------------
//客户端
    /*
实现步骤:
1.创建一个本地字节输入流FiLeInputstream对象,构造方法中绑定要读取的数据源
2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号
3.使用Socket中的方法getoutputstream,获取网络字节输出流OutputStream对象
4.使用本地字节输入流FileInputstream对家中的方法read,读职本地文件
5.使用网络字节输出流Outputstream对象中的方法write,把读取到的文件上传到服务器
6.使用Socket中的方法get InputStream,获取网络字节输入流Inputstream对象
7.使用网络字节输入流InFutstream对象中的方法read读取服务回写的数据
8.释放资源(FiLeInputstream,Socket)
 */

package 网络通信;

import java.io.*;
import java.net.Socket;

public class 文件上传客户端 {
    public static void main(String[] args) throws IOException {
        //1.创建一个本地字节输入流FiLeInputstream对象,构造方法中绑定要读取的数据源
        FileInputStream file = new FileInputStream("C:\\Users\\nj123\\Desktop\\1.png");
        //2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号
        Socket socket = new Socket("127.0.0.1", 8888);
        //3.使用Socket中的方法getoutputstream,获取网络字节输出流OutputStream对象
        OutputStream os = socket.getOutputStream();
        //4.使用本地字节输入流FileInputstream的方法read,读取本地文件
        int len=0;
        byte bytes[]=new byte [1024];//创建一个字节数组
        while((len=file.read(bytes))!=-1){
            //5.使用网络字节输出流Outputstream对象中的方法write,把读取到的文件上传到服务器
           os.write(bytes,0,len);
        }
//结束标志,表示写入结束,上传成功。没有这一句程序会进入阻塞状态。
        socket.shutdownOutput();
       // 6.使用Socket中的方法get InputStream,获取网络字节输入流Inputstream对象
        InputStream is = socket.getInputStream();
        //7.使用网络字节输入流InFutstream对象中的方法read读取服务回写的数据

        while((len=is.read(bytes))!=-1){
            System.out.println(new String(bytes,0,len));
        }
        //8.释放资源(FiLeInputstream,Socket)
        file.close();
        socket.close();
    }
}
---------------------------------------------------------
//服务器端
    /*
文件上传案例服务器端:读取客户端上传的文件,保存到服务器的硬盘,给客户端回写“上传成功“
明确:
数据源:客户端上传的文件
目的地:服务器的硬盘 d:\\upload\\1.jpg
实现步骤:
1.创建一个服务器Serversocket对象,和系统要指定的端口号
2.使用Serversocket对象中的方法accept,获取到请求的客户端Socket对象
3.使用Socket对象中的方法get Inputstream,获取到网络字节输入流Input Stream对象
4.判断d:\\upload文件夹是否存在,不存在则创建
5.创建一个本地字节输出流FiLeoutputStream对象,构造方法中绑定要输出的目的地
6.使用网络字节输入流Inputstream对象中的方法read,读取客户端上传的文件
7.使用本地字节输出流FiLeoutputstream对象中的方法write,把读取到的文件保存到服务器的硬盘上
8.使用Socket对象中的方法getoutputstream,获取到网络字节输出流OutputStream对象
9.使用网络字节输出流Outputstream对象中的方法write,给客户端回写“上传成功“
10.释放资源(FiLeoutputstrea,Socket,ServerSocket)
 */
package 网络通信;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class 文件上传服务器端 {
    public static void main(String[] args) throws IOException {
        //1.创建一个服务器Serversocket对象,和系统要指定的端口号
        ServerSocket server=new ServerSocket(8888);
        //2.使用Serversocket对象中的方法accept,获取到请求的客户端Socket对象
        Socket accept = server.accept();
        //3.使用Socket对象中的方法get Inputstream,获取到网络字节输入流Input Stream对象
        InputStream is= accept.getInputStream();
       // 4.判断d:\\upload文件夹是否存在,不存在则创建
        File f=new File("d:\\upload");
        if(!f.exists()){
            f.mkdir();
        }
        //5.创建一个本地字节输出流FiLeoutputStream对象,构造方法中绑定要输出的目的地
        FileOutputStream file=new FileOutputStream("d:\\upload\\1.jpg");
        //6.使用网络字节输入流Inputstream对象中的方法read,读取客户端上传的文件
        int len=0;
        byte bytes[]=new byte[1024];
        while ((len=is.read(bytes))!=-1){
            //7.使用本地字节输出流FiLeoutputstream对象中的方法write,把读取到的文件保存到服务器的硬盘上
            file.write(bytes,0,len);
        }
        //8.使用Socket对象中的方法getoutputstream,获取到网络字节输出流OutputStream对象
        OutputStream os = accept.getOutputStream();
        //9.使用网络字节输出流Outputstream对象中的方法write,给客户端回写“上传成功“
        os.write("上传成功".getBytes());
        //10.释放资源(FiLeoutputstrea,Socket,ServerSocket)
        file.close();
        accept.close();
        server.close();
    }


}
//客户端不会输出上传成功,两边的程序进入了阻塞状态。在客户端读取文件上传到服务器端时,read方法出现堵塞
//解决办法:在文件上传完以后,我们自己给服务器写一个结束标志;在Socket对象中有一个方法:void shutdownOutput​() 禁用此套接字的输出流。 


参考资料:Java黑马视频

posted @ 2020-12-22 21:50  胡木杨  阅读(484)  评论(0)    收藏  举报