欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

网络编程Socket_ServerSocket

程序员文章站 2022-05-04 10:07:47
...

软件结构

C/S结构 :全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、迅雷等软件;

B/S结构 :全称为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有谷歌、火狐等;

两种架构各有优势 ,但是都离不开网络编程;

网络通信:

网络通信协议:计算机必须穿遵循规则才能进行之间的通信;

TCP/IP协议:传输控制协议因特网互联协议( Transmission Control Protocol/Internet Protocol),是
Internet最基本、最广泛的协议

网络编程Socket_ServerSocket

TCP:面向连接(既需要三次握手);传输不会丢失数据;

UDP:不面向连接(不需要三次握手);传输会丢失数据;

网络编程三要素:IP+协议+端口

端口号:取值范围是0~65535,其中,0~1023之间的端口号用于一些知名的网络服务和应用

TCP通信程序

TCP通信能实现两台计算机之间的数据交互,通信的两端,要严格区分为客户端(Client)与服务端(Server)

1. 服务端程序,需要事先启动,等待客户端的连接

2. 客户端主动连接服务器端,连接成功才能通信。服务端不可以主动连接客户端

JAVA中提供了两个类Socket,ServerSocket实现通信程序;

网络编程Socket_ServerSocket

Socket类

public Socket(String host, int port)  :创建套接字对象并将其连接到指定主机上的指定端口号。如果指定的host是null ,则相当于指定地址为回送地址

public InputStream getInputStream()  返回此套接字的输入流;

public OutputStream getOutputStream()  返回此套接字的输出流;

public void close() 关闭此套接字

public void shutdownOutput()   禁用此套接字的输出流

ServerSocket类

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

public Socket accept() 侦听并接受连接,返回一个新的Socket对象,用于和客户端实现通信。该方法会一直阻塞直到建立连接

客户端文件上传,服务端文件保存案列

网络编程Socket_ServerSocket

优化思路:

1,图片文件名称写死的问题,可以使用时间戳解决;

2,循环接受,服务端可以一直接受客服端请求;

3,效率问题,可以匿名线程,多少个请求就开多少个线程;

客户端
public class FileUpload_Client {
    public static void main(String[] args) throws IOException {
        // 1.创建流对象
        // 1.1 创建输入流,读取本地文件
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("test.jpg"));
        // 1.2 创建输出流,写到服务端
        Socket socket = new Socket("localhost", 6666);
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        //2.写出数据.
        byte[] b  = new byte[1024 * 8 ];
        int len ;
        while (( len  = bis.read(b))!=‐1) {
            bos.write(b, 0, len);
        }
       // 关闭输出流,通知服务端,写出数据完毕  
        socket.shutdownOutput();
        System.out.println("文件发送完毕");
        // 3. =====解析回写============
        InputStream in = socket.getInputStream();
        byte[] back = new byte[20];
        in.read(back);
        System.out.println(new String(back));
        in.close();
        // ============================
        // 4.释放资源
        socket.close();
        bis.close();
    }
}


服务端
public class FileUpload_Server {
    public static void main(String[] args) throws IOException {
        System.out.println("服务器 启动.....  ");
        // 1. 创建服务端ServerSocket
        ServerSocket serverSocket = new ServerSocket(6666);
        // 2. 循环接收,建立连接
        while (true) {
            Socket accept = serverSocket.accept();
           /*  
           3. socket对象交给子线程处理,进行读写操作  
               Runnable接口中,只有一个run方法,使用lambda表达式简化格式
            */
            new Thread(() ‐> {
                try (
                    //3.1 获取输入流对象
                    BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());
                    //3.2 创建输出流对象, 保存到本地 .
                    FileOutputStream fis = new FileOutputStream(System.currentTimeMillis() +
".jpg");
                    BufferedOutputStream bos = new BufferedOutputStream(fis);
                ) {
                    // 3.3 读写数据
                    byte[] b = new byte[1024 * 8];
                    int len;
                    while ((len = bis.read(b)) != ‐1) {
                        bos.write(b, 0, len);
                    }
                    // 4.=======信息回写===========================
                    System.out.println("back ........");
                    OutputStream out = accept.getOutputStream();
                    out.write("上传成功".getBytes());
                    out.close();
                    //================================
                    //5. 关闭 资源
                    bos.close();
                    bis.close();
                    accept.close();
                    System.out.println("文件上传已保存");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

模拟B\S服务器

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(8888);
        while(true){
            Socket socket = server.accept();
            new Thread(new Web(socket)).start();
        }
    }
    static class Web implements Runnable{
        private Socket socket;
        public Web(Socket socket){
            this.socket=socket;
        }
        public void run() {
            try{
                //转换流,读取浏览器请求第一行
                BufferedReader readWb = new
                        BufferedReader(new InputStreamReader(socket.getInputStream()));
                String requst = readWb.readLine();
                //取出请求资源的路径
                String[] strArr = requst.split(" ");
                System.out.println(Arrays.toString(strArr));
                String path = strArr[1].substring(1);
                System.out.println(path);
                FileInputStream fis = new FileInputStream(path);
                System.out.println(fis);
                byte[] bytes= new byte[1024];
                int len = 0 ;
                //向浏览器 回写数据
                OutputStream out = socket.getOutputStream();
                out.write("HTTP/1.1 200 OK\r\n".getBytes());
                out.write("Content‐Type:text/html\r\n".getBytes());
                out.write("\r\n".getBytes());
                while((len = fis.read(bytes))!=‐1){
                    out.write(bytes,0,len);
                }
                fis.close();
                out.close();
                readWb.close();
                socket.close();
            }catch(Exception ex){
            }
        }
    }
}

 

相关标签: JAVA进阶