网络编程-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文件夹,文件夹中就会包括上传的文件(这里这个文件夹就是模拟的服务器中的文件夹)

 

 

猜你喜欢

转载自www.cnblogs.com/excellencesy/p/9184992.html