JAVA学习笔记18 网络编程之TCP通信(2)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

TCP模型下基础的Client-Server发送消息与接收消息

Sever:

package Net;

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

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        //创建服务器端的socket对象
        ServerSocket ss=new ServerSocket(1998);
			
        //侦听客户端的连接
        Socket s=ss.accept();
				
        //获取输入流,读数据
        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];
        int len = is.read(bys);
        String data = new String(bys,0,len);
        System.out.println(data);

        s.close();
        ss.close();
    }
}

Client:

package Net;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端Socket对象
        Socket s=new Socket(InetAddress.getByName("LAPTOP-ATCGV4AQ"),1998);

        //获取输出流,写数据
        OutputStream os=s.getOutputStream();
        os.write("  hello,tcp,我来辣".getBytes());

        s.close();
    }
}

执行结果:
在这里插入图片描述

TCP模型下Client-Server同时发送消息与接收消息

Client:

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端Socket对象
        Socket s=new Socket(InetAddress.getByName("LAPTOP-ATCGV4AQ"),1998);

        //获取输出流,写数据
        OutputStream os=s.getOutputStream();
        os.write("hello,tcp,我来辣".getBytes());

        InputStream is=s.getInputStream();
        byte[] bys=new byte[1024];
        int len=is.read(bys);
        String data=new String(bys,0,len);
        System.out.println("客户端接收到:"+data);


        s.close();
    }
}

Server:

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        //创建服务器端的socket对象
        ServerSocket ss=new ServerSocket(1998);

        //侦听客户端的连接
        Socket s=ss.accept();

        //获取输入流,读数据
        InputStream is=s.getInputStream();
        byte[] bys=new byte[1024];
        int len =is.read(bys);
        String data=new String(bys,0,len);
        System.out.println(data);

        OutputStream os=s.getOutputStream();
        os.write("客户端接收到数据了".getBytes());

        s.close();
        ss.close();

    }
}

执行结果:
在这里插入图片描述
在这里插入图片描述

TCP模型下Client-Server使用字符流发送消息与接收消息并且只有当Client发送886时结束通信

Client

package Net.TCP.Client01Demo;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;

public class Client {
    public static void main(String[] args) throws IOException {
        Socket s = new Socket(InetAddress.getByName("LAPTOP-ATCGV4AQ"), 1998);

        //数据来自于键盘录入,直到输入的数据是886为止
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //封装字节流输出
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        //s.getOutputStream()字节流,new OutputStreamWriter转换为字符流,new BufferedWriter为了与上面的BufferedReader对应而采用
        BufferedReader brReceive = new BufferedReader(new InputStreamReader(s.getInputStream()));//获取收到的回复信息
        String Line;
        while ((Line = br.readLine()) != null) {
            if ("886".equals(Line)) {
                System.out.println("886,结束通信");
                break;
            } else {
                //获取输出流对象,但是此方法为字节流方法,我们采取自己封装字节流的方式传输
                //OutputStream os = s.getOutputStream();
                //os.write(Line.getBytes());

                //字符流输出数据给server端
                bw.write(Line);
                bw.newLine();
                bw.flush();
            }

            System.out.println("收到Server回复 : "+brReceive.readLine());
        }

        br.close();
        bw.close();
        brReceive.close();
        s.close();
    }
}

Server:

package Net.TCP.Client01Demo;

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

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(1998);
        Socket s = ss.accept();

        BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        String Line;
        while ((Line=br.readLine())!=null){
            System.out.println("本地接受到数据"+Line);
            //回复收到
            bw.write("服务器已收到数据"+Line);
            bw.newLine();
            bw.flush();
            if ("886".equals(br)){
                break;
            }
        }

        bw.close();
        br.close();
        s.close();
        ss.close();
    }
}

在这里插入图片描述Client:

public class Client {
    public static void main(String[] args) throws IOException {
        Socket s=new Socket(InetAddress.getByName("LAPTOP-ATCGV4AQ"), 1998);

        BufferedReader br=new BufferedReader(new FileReader("ieda_test\\src\\IO\\fos.txt"));
        //BufferedReader br2=new BufferedReader(new InputStreamReader(new FileInputStream("ieda_test\\src\\IO\\fos.txt")));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        //s.getOutputStream()字节流,new OutputStreamWriter转换为字符流,new BufferedWriter为了与上面的BufferedReader对应而采用
        BufferedReader brReceive = new BufferedReader(new InputStreamReader(s.getInputStream()));//获取收到的回复信息
        String Line;
        while ((Line = br.readLine()) != null) {
                //获取输出流对象,但是此方法为字节流方法,我们采取自己封装字节流的方式传输
                //OutputStream os = s.getOutputStream();
                //os.write(Line.getBytes());

                //字符流输出数据给server端
                bw.write(Line);
                bw.newLine();
                bw.flush();
//            System.out.println("收到Server回复 : "+brReceive.readLine());
            //brReceive.readLine()会导致一直等到服务器端的回复数据才会停止,所以这个地方容易死等
        }

        //自定义结束标记
//        bw.write("886");
//        bw.newLine();
//        bw.flush();

        s.shutdownOutput();//这个shutdown的含义就是通过s向server端口发送终止信号,表明已经传输完成了	

        br.close();
        bw.close();
        brReceive.close();
        s.close();
    }

}

这个shutdown的含义就是通过s向server端口发送终止信号,表明已经传输完成了 这样sever端就可以停止接受client端的消息而不会进入无限等待中。

Server:

package Net.TCP.Client02Demo;

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

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(1998);
        Socket s = ss.accept();

        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        //把接收到的数据复制到另外一个本地文件中
        BufferedWriter bwLocal = new BufferedWriter(new FileWriter("ieda_test\\src\\Net\\TCP\\Client02Demo\\Local.txt"));

        String Line;
        while ((Line = br.readLine()) != null) {
            //复制到本地
            bwLocal.write(Line);
            bwLocal.newLine();
            bwLocal.flush();
            System.out.println("本地接受到数据" + Line);


        }
        //回复收到
        bw.write("服务器已收到数据" + Line);
        bw.newLine();
        bw.flush();


        bw.close();
        br.close();
        s.close();
        ss.close();
        bwLocal.close();
    }
}

执行结果:
在这里插入图片描述
文件上传成功!

需要注意的是:在Client中brReceive.readLine()会导致一直等到服务器端的回复数据才会停止,所以这个地方容易死等。

在这里插入图片描述
Client:

public class Client {
    public static void main(String[] args) throws IOException {
        Socket s=new Socket(InetAddress.getByName("LAPTOP-ATCGV4AQ"), 1998);

        BufferedReader br=new BufferedReader(new FileReader("ieda_test\\src\\IO\\fos.txt"));
        //BufferedReader br2=new BufferedReader(new InputStreamReader(new FileInputStream("ieda_test\\src\\IO\\fos.txt")));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        //s.getOutputStream()字节流,new OutputStreamWriter转换为字符流,new BufferedWriter为了与上面的BufferedReader对应而采用
        BufferedReader brReceive = new BufferedReader(new InputStreamReader(s.getInputStream()));//获取收到的回复信息
        String Line;
        while ((Line = br.readLine()) != null) {
            //字符流输出数据给server端
            bw.write(Line);
            bw.newLine();
            bw.flush();
        }


        s.shutdownOutput();
        System.out.println("收到Server回复 : "+brReceive.readLine());

        br.close();
        bw.close();
        brReceive.close();
        s.close();
    }

}

Server:

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket ss=new ServerSocket(1998);

        //为每个客户端Client开启一个线程
        while (true){
            Socket s=ss.accept();
            new Thread(new ServerThread(s)).start();
        }

    }
}

ServerThread:

public class ServerThread implements Runnable {
    public Socket s;
    public ServerThread(Socket s) {
        this.s=s;
    }

    @Override
    public void run() {
        //接收数据写到文件中
        try {
            BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));

            //解决名称冲突问题
            int count = 0;
            File file =new File("ieda_test\\src\\Net\\TCP\\Client03Demo\\Copy["+count+"].txt");
            while (file.exists()){
                count++;
                file =new File("ieda_test\\src\\Net\\TCP\\Client03Demo\\Copy["+count+"].txt");
            }
            BufferedWriter bw=new BufferedWriter(new FileWriter(file));

            String line;
            while ((line=br.readLine())!=null){
                bw.write(line);
                bw.newLine();
                bw.flush();
            }

            //给client反馈收到
            BufferedWriter bwServer=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            bwServer.write("文件上传成功");
            bwServer.newLine();
            bwServer.flush();

            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

执行结果:

文件上传成功!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值