• 网络编程-tcp


    一、简单的demo

    (1)客户端

    package com.songyan.tcp;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.ObjectInputStream.GetField;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class Demo_Client {
        /**
        * 1.客户端
        * 创建Socket连接服务端(指定ip地址,端口号)通过ip地址找对应的服务器
        * 调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的IO流
        * 输入流可以读取服务端输出流写出的数据
        * 输出流可以写出数据到服务端的输入流
        * @param args
         * @throws IOException 
         * @throws UnknownHostException 
        */
        public static void main(String[] args) throws UnknownHostException, IOException {
            //创建socket
            Socket socket=new Socket("127.0.0.1",12345);
            //创建输入流
            InputStream in=socket.getInputStream();
            //创建输出流
            OutputStream out=socket.getOutputStream();    
            
            //接受服务器返回的数据
            byte[] respo=new byte[1024];
            int len =in.read(respo);
            System.out.println(new String(respo,0,len));
            
            out.write("学习计算机哪家强".getBytes());
        }
    
    }

    (2)服务器端

    package com.songyan.tcp;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    
    
    public class Demo_server {
        /*2.服务端
         * com/songyan/tcp/Demo_server.java
        * 创建ServerSocket(需要指定端口号)
        * 调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket
        * 调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流
        * 输入流可以读取客户端输出流写出的数据
        * 输出流可以写出数据到客户端的输入流*/
    
        public static void main(String[] args) throws IOException {
            //创建socket
            ServerSocket serversocket=new ServerSocket(12345);
            //接受客户端的请求
            Socket socket=serversocket.accept();
            //获取输入流
            InputStream in=socket.getInputStream();
            OutputStream out =socket.getOutputStream();
            //服务器向客户端写数据
            out.write("百度一下你就知道".getBytes());
    
            //服务器读取客户端发送的请求
            byte[] respo=new byte[1024];
            int len =in.read(respo);
            System.out.println(new String(respo,0,len));
        }
    }

    (3)运行

    在bin目录下(按住shift右键----在此处打开命令行窗口)

     

    输入start打开另一个窗口

    在其中一个窗口,先运行服务器端的程序

    在另一个窗口运行客户端的程序

     二、TCP代码优化(输入字符串/一行)

    (1)客户端

    package com.songyan.tcp;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.ObjectInputStream.GetField;
    import java.io.OutputStream;
    import java.io.PrintStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class Demo2_Client {
        /**
        * 1.客户端
        * 创建Socket连接服务端(指定ip地址,端口号)通过ip地址找对应的服务器
        * 调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的IO流
        * 输入流可以读取服务端输出流写出的数据
        * 输出流可以写出数据到服务端的输入流
        * @param args
         * @throws IOException 
         * @throws UnknownHostException 
        */
        public static void main(String[] args) throws UnknownHostException, IOException {
            //创建socket
            Socket socket=new Socket("127.0.0.1",12345);
            BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintStream ps=new PrintStream(socket.getOutputStream());
            //接受服务器返回的数据
            System.out.println(br.readLine());
            ps.println("我想报名");
            System.out.println(br.readLine());
            
            
        }
    
    }

     

    (2)服务器端

    package com.songyan.tcp;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.PrintStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    
    
    public class Demo2_server {
        /*2.服务端
         * com/songyan/tcp/Demo_server.java
        * 创建ServerSocket(需要指定端口号)
        * 调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket
        * 调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流
        * 输入流可以读取客户端输出流写出的数据
        * 输出流可以写出数据到客户端的输入流*/
    
        public static void main(String[] args) throws IOException {
            //创建socket
            ServerSocket serversocket=new ServerSocket(12345);
            //接受客户端的请求
            Socket socket=serversocket.accept();
            //获取输入流
            BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintStream ps=new PrintStream(socket.getOutputStream());
            //服务器向客户端写数据
            ps.println("欢迎访问黑马程序员");
            System.out.println(br.readLine());
            ps.println("爆满了");
            
        }
    }

     

     

     三、服务端是多线程的

    多线程的时候只需要修改服务器端

    package com.songyan.tcp;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.PrintStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    
    
    public class Demo3_server {
        /*2.服务端
         * com/songyan/tcp/Demo_server.java
        * 创建ServerSocket(需要指定端口号)
        * 调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket
        * 调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流
        * 输入流可以读取客户端输出流写出的数据
        * 输出流可以写出数据到客户端的输入流*/public static void main(String[] args) throws IOException {
            //创建socket
            ServerSocket serversocket=new ServerSocket(12345);
            while(true)
            {
                final Socket socket=serversocket.accept();
                new Thread(){
                    public void run(){
                        try {
                            //接受客户端的请求
                            
                            //获取输入流
                            BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                            PrintStream ps=new PrintStream(socket.getOutputStream());
                            //服务器向客户端写数据
                            ps.println("欢迎访问黑马程序员");
                            System.out.println(br.readLine());
                            ps.println("爆满了");
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    
                }.start();
            }
        }
    }

     

    练习题1, 客户端向服务器写字符串(键盘录入),服务器(多线程)将字符串反转后写回,客户端再次读取到是反转后的字符串

     (1)客户端

    package com.songyan.tcp;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.PrintStream;
    import java.net.Socket;
    import java.util.Scanner;
    
    public class Demo5_Client {
        public static String reversel(String str){  
            return new StringBuffer(str).reverse().toString();  
        }  
        /*客户端向服务器写字符串(键盘录入)*/
        public static void main(String[] args) throws IOException {
            //创建Socket
            Socket socket=new Socket("127.0.0.1",12346);
            //获取输入流,输出流
            BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintStream ps=new PrintStream(socket.getOutputStream());
            //接受服务器的数据
            String message=br.readLine();
            System.out.println(reversel(message));
            //再次向客户端发送数据
            Scanner in=new Scanner(System.in);
            ps.println(in.nextLine());
            message=br.readLine();
            System.out.println(reversel(message));
            ps.println(in.nextLine());
            
            
        }
    }

    (2)服务器端

    package com.songyan.tcp;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Scanner;
    
    public class Demo5_server {
        /*服务器(多线程)将字符串反转后写回,
         * 客户端再次读取到是反转后的字符串*/
        public static void main(String[] args) throws IOException {
            //创建服务器端socket
            ServerSocket serverSocket=new ServerSocket(12346);
            //获取客户端的输入
            final Socket socket=serverSocket.accept();
            new Thread(){
                public void run()
                {
                    //获取输入流对象,输出流对象
                    try {
                        BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        PrintStream ps=new PrintStream(socket.getOutputStream());
                        //输出数据给客户端
                        Scanner in=new Scanner(System.in);
                        ps.println(in.nextLine());
                        System.out.println(br.readLine());
                        ps.println(in.nextLine());
                        System.out.println(br.readLine());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                
            }.start();
                
            
        }
    }

     

    习题2, 客户端向服务器上传文件

    (1)客户端

    package com.songyan.file;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.Scanner;
    
    import javax.xml.ws.handler.MessageContext.Scope;
    
    public class Demo1_Client {
        public static  File getFile()
        {
            System.out.println("请输入文件路径");
            Scanner sc=new Scanner(System.in); 
            String path=sc.nextLine();          //获取文件路径
            File file=new File(path);           //文件名封装成文件
            while(true)
            {
                if(!file.exists())
                {
                    System.out.println("文件不存在,请重新输入");
                }else if(file.isDirectory())
                {
                    System.out.println("您输入的是文件夹名称,请输入文件名称");
                }else{
                    return file;
                }
            }
        }
        public static void main(String[] args) throws UnknownHostException, IOException {
            //提示输入上传的文件路径,判断路径是否存在,是否是文件夹
            File file=getFile();
            //发送文件名到服务端
            Socket socket=new Socket("127.0.0.1",12345);
            BufferedReader  br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintStream ps=new PrintStream(socket.getOutputStream());
            ps.println(file.getName());        
            //接受结果
            String result=br.readLine();
            //如果存在,给予提示,程序直接退出
            if("存在".equals(result))
            {
                System.out.println("文件已存在");
                socket.close();
                return;
            }else{
                //如果不存在,定义FileInputStream读取文件,写出到网络
                FileInputStream fileIn=new FileInputStream(file);
                byte[] arr=new byte[8192];
                int len;
                while((len=fileIn.read(arr)) != -1)
                {
                    ps.write(arr,0,len);
                }
                fileIn.close();
                socket.close();
                
            }
            
            
            
            
        }
    }

    (2)服务器端

    package com.songyan.file;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.PrintStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class Demo1_Server {
        public static void main(String[] args) throws IOException {
            //建立多线程服务器
            ServerSocket server=new ServerSocket(12345);
            //读取文件名
            while(true)
            {
                final Socket socket= server.accept();
                new Thread(){
                    public void run()
                    {
                        try {
                            InputStream in= socket.getInputStream();
                            BufferedReader br=new BufferedReader(new InputStreamReader(in));
                            PrintStream ps=new PrintStream(socket.getOutputStream());
                            String filename=br.readLine();
                            //判断文件是否存在,结果返回给客户端
                            File dir=new File("path");
                            dir.mkdir();
                            File file=new File(dir,filename);
                            if(file.exists())
                            {
                                ps.println("存在");
                                socket.close();
                                return;
                            }else{
                                ps.println("不存在");
                            }
                            //定义FileOutputStream,从网络读取数据存储到本地
                            FileOutputStream out=new FileOutputStream(file);
                            byte[] arr= new byte[8192];
                            int  len ;
                            while((len=in.read(arr))==-1)
                            {
                                out.write(arr,0,len);
                            }
                            out.close();
                            socket.close();
                            
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        
                    }
                    
                }.start();
                
            }  
        }
    } 

     

    运行后在项目的根路径下就会创建path文件夹,文件夹中就会包括上传的文件(这里这个文件夹就是模拟的服务器中的文件夹)

     

     

  • 相关阅读:
    16 | 网络优化(中):复杂多变的移动网络该如何优化?
    Understanding Temporal Metrics
    Objective-C Runtime 大佬系列文章整理
    面向对象编程中的封装、抽象、继承、多态特性以及应用
    面向接口编程原理
    一次HTTP请求的完整过程——协议篇(DNS、TCP、HTTP)
    计算机网络 | 图解 DNS & HTTPDNS 原理
    CDN的加速原理是什么?
    让WKWebview支持NSURLProtocol总结
    WKWebView 请求拦截
  • 原文地址:https://www.cnblogs.com/excellencesy/p/9184992.html
Copyright © 2020-2023  润新知