Java网络编程

文章目录

  • Java网络编程
    • IP
      • IPv4
      • IPv6
      • IPv4的地址分类形式
      • 特殊的IP地址
      • 常用的cmd命令
      • InetAddress
    • 端口号
    • 协议
      • UDP协议
        • 发送数据
        • 接收数据
        • 练习
        • UDP三种通信方式
      • TCP协议
        • 客户端Cilent
        • 服务器端Server
        • 解决输出流中文乱码问题
        • 三次握手四次挥手
          • 三次握手
          • 四次挥手
    • 综合练习
      • 多发多收
      • 接受并反馈
      • 上传文件
        • 上传文本文件
        • 上传图片
      • 文件名重复
      • 多线程的服务端
      • 线程池版的服务端
      • BS架构模型
      • 控制台版聊天室

Java网络编程

什么网络编程?

计算机跟计算机之间通过网络进行数据传输

常见软件架构有哪些?

CS/BS

通信的软件架构CS\BS的各有什么区别和优缺点

CS:客户端服务端模式需要开发客户端

BS:浏览器服务端模式不需要开发客户端

CS:适合定制专业化的办公类软件如: IDEA、网游

BS:适合移动互联网应用,可以在任何地方随时访问的系统

网络编程三要素

IP:设备在网络中的地址,是唯一的标识

端口号:应用程序在设备中唯一的标识

协议:数据在网络中传输的规则,常见的协议有UDP、TCP、http、https、ftp

IP

IPv4

Java网络编程_第1张图片

IPv6

Java网络编程_第2张图片

Java网络编程_第3张图片

IPv4的地址分类形式

  • 公网地址(万维网)和私有地址(局域网)
  • 192.168.开头的就是私有地址,范围为192.168.0.0-192.168.255.255,专门为组织机构内部使用,一次节省IP

Java网络编程_第4张图片

特殊的IP地址

127.0.0.1,也可以是localhost: 是回送地址也称本地回环地址,也称本机IP,永远只会寻找当前所在本机。

如果是自己主机给自己主机发送信息,直接用127.0.0.1,永远表示本机。

常用的cmd命令

查看本机IP:ipconfig

查看是否连通:ping

ping www.baidu.com

InetAddress

import java.net.InetAddress;  //实现网络应用程序
import java.net.UnknownHostException;

public class net {
    public static void main(String[] args) throws UnknownHostException {
        InetAddress adderss1=InetAddress.getByName("XXXX");  //在给定主机名或IP情况下生成主机对象
        System.out.println(adderss1);

        InetAddress address2=InetAddress.getLocalHost();  //返回本地主机
        System.out.println(address2);

        String name=adderss1.getHostName();  //主机名
        System.out.println(name);

        String ip=adderss1.getHostAddress();  //主机ip
        System.out.println(ip);
    }
}

端口号

应用程序在设备中唯一的标识。

由两个字节表示的整数,取值范围: 0~65535

其中0~1023之间的端口号用于一些知名的网络服务或者应用,我们自己使用1024以上的端口号就可以了。

注意:一个端口号只能被一个应用程序使用。

协议

Java网络编程_第5张图片

Java网络编程_第6张图片

Java网络编程_第7张图片

UDP协议

发送数据
import java.io.IOException;
import java.net.*;

public class send {
   public static void main(String[] args) throws IOException {
       //第一步:创建DatagramSocket对象(找快递公司)
       DatagramSocket ds=new DatagramSocket();

       //第二步:准备发送内容,地址,端口号
       String str="cjm is pig!!";
       byte[] strBytes=str.getBytes();
       InetAddress address=InetAddress.getByName("127.0.0.1");
       int port=10086;  //指定发送端口

       //第三步:DatagramPacket打包
       DatagramPacket dp=new DatagramPacket(strBytes, strBytes.length,address,port);

       //第四步:发送
       ds.send(dp);

       //第五步:释放
       ds.close();
   }
}
接收数据
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class receive {
   public static void main(String[] args) throws IOException {

       //第一步:创建DatagramSocket对象,绑定发送端口
       DatagramSocket ds = new DatagramSocket(10086);

       //第二步:准备接收数据的DatagramPacket
       byte[] bytes = new byte[1024];
       DatagramPacket dp = new DatagramPacket(bytes, bytes.length);

       //第三步:接收数据
       ds.receive(dp);  //程序运行到这里会阻塞,等待发送方发送数据才能继续运行

       //第四步:解析数据包
       byte[] data = dp.getData();
       int len = dp.getLength();
       System.out.println("发送地址:" +dp.getAddress() + " 发送端口:" + dp.getPort() + " 发送内容:" + new String(data, 0, len));

       //第五步:释放
       ds.close();
   }
}

注意:要先运行receive类,再运行send类,receive类才能接收到数据。

练习

按照下面的要求实现程序:

UDP发送数据:数据来自于键盘录入,直到输入的数据是886,发送数据结束

UDP接收数据:因为接收端不知道发送端什么时候停止发送,故采用死循环接收

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class testSend {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds=new DatagramSocket();

        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入您要发送的信息:");
        while(true){
            String str=scanner.nextLine();  //一次发送一行
            if(str.equals("886")){
                break;
            }
            byte[] bytes=str.getBytes();
            InetAddress address=InetAddress.getByName("127.0.0.1");
            int port=10086;

            DatagramPacket dp=new DatagramPacket(bytes, bytes.length,address,port);

            ds.send(dp);
        }
        ds.close();
    }
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class testReceive {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds=new DatagramSocket(10086);

        byte[] bytes=new byte[1024];
        DatagramPacket dp=new DatagramPacket(bytes, bytes.length);

        while(true){
            ds.receive(dp);

            byte[] data=dp.getData();
            int len=dp.getLength();
            System.out.println("地址:端口号 "+dp.getAddress()+":"+dp.getPort()+" 发送信息:"+new String(data,0,len));
        }
    }
}
UDP三种通信方式
  • 单播

一对一

  • 组播

一对一组电脑

组播地址:224.0.0.0-239.255.255.255,其中224.0.0.0~224.0.0.255为预留的组播地址。

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class send {
    public static void main(String[] args) throws IOException {
        //创建MulticastSocket对象
        MulticastSocket multicastSocket=new MulticastSocket();

        String str="cjm is pig";
        byte[] bytes=str.getBytes();
        InetAddress address=InetAddress.getByName("224.0.0.1");  //组播地址
        int port=10086;
        
        DatagramPacket dp=new DatagramPacket(bytes, bytes.length,address,port);
        multicastSocket.send(dp);
        
        multicastSocket.close();
    }
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class receive1 {
    public static void main(String[] args) throws IOException {
        //创建MulticastSocket对象
        MulticastSocket multicastSocket = new MulticastSocket(10086);

        byte[] bytes = new byte[1024];

        //将当前主机加入224.0.0.1这一组
        InetAddress address = InetAddress.getByName("224.0.0.1");
        multicastSocket.joinGroup(address);

        DatagramPacket dp = new DatagramPacket(bytes, bytes.length);

        multicastSocket.receive(dp);

        byte[] data = dp.getData();
        int len = dp.getLength();
        System.out.println("地址:端口" + dp.getAddress() + ":" + dp.getPort() + " 发送信息:" + new String(data, 0, len));

        multicastSocket.close();

    }
}
  • 广播

一对局域网中所有的电脑

广播地址:255.255.255.255。

import java.io.IOException;
import java.net.*;

public class send {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket();

        String str = "cjm is pig";
        byte[] strBytes = str.getBytes();
        InetAddress address = InetAddress.getByName("255.255.255.255");  //给局域网里面所有的地址发送数据
        int port = 10086;

        DatagramPacket dp = new DatagramPacket(strBytes, strBytes.length, address, port);

        ds.send(dp);

        ds.close();
    }
}

TCP协议

Java网络编程_第8张图片

Java网络编程_第9张图片

客户端Cilent
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
    public static void main(String[] args) throws IOException {
        //1.创建socket,并且设置服务器的地址和端口号
        Socket  socket=new Socket("127.0.0.1",10086);  //在创建对象的同时会连接服务器,如果连不上,代码会报错

        //2.获取输出流
        OutputStream os=socket.getOutputStream();
        os.write("cjm is pig.".getBytes());  //中文会乱码

        //3.释放资源
        os.close();
        socket.close();
    }
}
服务器端Server
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) throws IOException {
        //1.创建ServerSocket
        ServerSocket ss=new ServerSocket(10086);  //绑定端口

        //2.监听客户端的连接,一但连接返回连接对象
        Socket socket=ss.accept();  //阻塞,直到客户端请求连接,有连接返回连接对象

        //3.从连接通道中获取输入流
        InputStream is=socket.getInputStream();
        int b;
        while((b=is.read())!=-1){
            System.out.print((char)b);
        }

        //4.释放资源
        socket.close();  //关闭连接通道
        ss.close();  //断开连接

    }
}
解决输出流中文乱码问题
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
    public static void main(String[] args) throws IOException {
        //1.创建socket,并且设置服务器的地址和端口号
        Socket  socket=new Socket("127.0.0.1",10086);  //在创建对象的同时会连接服务器,如果连不上,代码会报错

        //2.获取输出流
        OutputStream os=socket.getOutputStream();
        os.write("cjm是猪!!!".getBytes());

        //3.释放资源
        os.close();
        socket.close();  //利用四次挥手协议断开连接,确保连接通道里面的数据全部处理完毕
    }
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) throws IOException {
        //1.创建ServerSocket
        ServerSocket ss=new ServerSocket(10086);  //Server绑定端口号

        //2.监听客户端的连接,一但连接返回连接对象
        Socket socket=ss.accept();

        //3.从连接通道中获取输入流
        InputStream is=socket.getInputStream();

        //解决中文乱码,把字节流转换成字符流
        InputStreamReader isr=new InputStreamReader(is);
        //提高读取效率
        BufferedReader br=new BufferedReader(isr);  //缓冲流
        int b;
        while((b=br.read())!=-1){
            System.out.print((char)b);
        }

        //4.释放资源
        socket.close();  //关闭连接通道
        ss.close();  //断开连接

    }
}
三次握手四次挥手
三次握手

Java网络编程_第10张图片

四次挥手

Java网络编程_第11张图片

综合练习

多发多收

客户端:多次发送数据

服务器:接收多次数据并打印

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) throws IOException {
        Scanner sc=new Scanner(System.in);
        Socket socket=new Socket("127.0.0.1",10086);
        OutputStream os= socket.getOutputStream();
        while(true){
            System.out.println("请输入发送的信息:");
            String str=sc.nextLine();  //按行发送
            if(str.equals("886")){
                System.out.println("发送结束!");
                break;
            }
            os.write(str.getBytes());
            System.out.println("发送完成!");
        }
        os.close();
        socket.close();
    }
}
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket ss=new ServerSocket(10086);

        Socket socket=ss.accept();
        InputStream is=socket.getInputStream();
        InputStreamReader isr=new InputStreamReader(is);
        BufferedReader br=new BufferedReader(isr);

        System.out.println("----------开始接收信息----------");
        System.out.println("地址:端口号"+socket.getInetAddress()+":"+socket.getPort()+"发送的信息为:");
        int b;
        while((b=br.read())!=-1){
            System.out.print((char)b);
        }
    }
}

程序会一直执行br.read(),多次读取到的内容并没有换行。

问题所在:

Scanner sc=new Scanner(System.in); String str=sc.nextLine();

sc.nextLine() 返回的是结束符之前的内容,并不会返回结束符,想要服务端输出有换行还需要在输入的字符后加一个换行符。

while(true){
            System.out.println("请输入发送的信息:");
            String str=sc.nextLine();  //按行发送,返回的是结束符之前的内容,并不会返回结束符
            if(str.equals("886")){
                System.out.println("发送结束!");
                break;
            }
            str=str+'\n';  //加一个换行符
            os.write(str.getBytes());
            System.out.println("发送完成!");
        }

接受并反馈

客户端:发送一条数据,接收服务端反馈的信息并打印

服务器:接收数据并打印,再给客户端反馈消息

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

public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket=new Socket("127.0.0.1",10086);
        OutputStream os=socket.getOutputStream();  //打开输出流
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入要发送的信息:");
        String str=sc.nextLine();
        str=str+"\n";
        os.write(str.getBytes());
        System.out.println("发送成功!");

        socket.shutdownOutput();  //关闭输出流

        System.out.println("开始接收反馈信息----------------");
        InputStream is= socket.getInputStream();  //打开输入流
        InputStreamReader isr=new InputStreamReader(is);
        BufferedReader br=new BufferedReader(isr);
        int b;
        while((b=br.read())!=-1){
            System.out.print((char)b);
        }
        System.out.println("接收反馈信息成功!");
        socket.close();
    }
}
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(10086);
        Socket socket=ss.accept();
        InputStream is=socket.getInputStream();  //打开输入流
        InputStreamReader isr=new InputStreamReader(is);
        BufferedReader br=new BufferedReader(isr);

        System.out.println("接收到的信息为:");
        int b;
        while((b=br.read())!=-1){
            System.out.print((char)b);
        }

        System.out.println("开始发送反馈信息----------------");
        OutputStream os= socket.getOutputStream();  //打开输出流
        String str="服务端反馈信息:cjm是猪!\n";
        os.write(str.getBytes());
        System.out.println("发送反馈信息成功!");
        socket.close();
        ss.close();
    }
}

上传文件

上传文本文件
import java.io.*;
import java.net.Socket;

public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket=new Socket("127.0.0.1",10086);

        //InputStream读取文件
        BufferedInputStream bis=new BufferedInputStream(new FileInputStream("net\\file\\22.txt"));

        //创建输出流OutputStream
        BufferedOutputStream bos=new BufferedOutputStream(socket.getOutputStream());

        //将文件读到字节数组后输出
        byte[] bytes=new byte[1024];
        int len;
        //read(byte[] data);从输入流里面读取若干字节装填到给定的数组里面
        //如果输入流中字节足够则填满,否则只装填前面的部分.返回实际装填长度
        while((len=bis.read(bytes))!=-1){  //输入流读入
            bos.write(bytes,0,len);  //输出流输出
        }
        bos.flush();  //刷新此缓冲的输出流
        //使用outputstream写文件没有bos.flush();会导致文本文件内容缺失

        socket.shutdownOutput();  //关闭输出流

        //打开输入流接收反馈信息
        BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String str=br.readLine();
        System.out.println(str);

        //关闭通道
        socket.close();
    }
}
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(10086);

        Socket socket=ss.accept();

        //输入流接收文件
        BufferedInputStream bis=new BufferedInputStream(socket.getInputStream());

        //输出流保存文件
        BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("net\\fileout\\22.txt"));

        //在输入流读取文件到字节数组再用输出流保存文件
        byte[] bytes=new byte[1024];
        int len;
        while((len=bis.read(bytes))!=-1){
            bos.write(bytes,0,len);
        }
        bos.flush();  //刷新此缓冲的输出流
        //使用outputstream写文件没有bos.flush();会导致文本文件内容缺失

        //打开输出流发送反馈信息
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bw.write("上传成功!");
        bw.newLine();  //写入一个行分隔符
        bw.flush();

        socket.close();
        ss.close();
    }
}

注意:记得关闭输入输出流。

上传图片
import java.io.*;
import java.net.Socket;

public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket=new Socket("127.0.0.1",10086);

        //InputStream读取文件
        BufferedInputStream bis=new BufferedInputStream(new FileInputStream("net\\file\\11.png"));

        //创建输出流OutputStream
        BufferedOutputStream bos=new BufferedOutputStream(socket.getOutputStream());

        //将文件读到字节数组后输出
        byte[] bytes=new byte[1024];
        int len;
        //read(byte[] data);从输入流里面读取若干字节装填到给定的数组里面
        //如果输入流中字节足够则填满,否则只装填前面的部分.返回实际装填长度
        while((len=bis.read(bytes))!=-1){  //输入流读入
            bos.write(bytes,0,len);  //输出流输出
        }
        bos.flush();  //刷新此缓冲的输出流
        //使用outputstream写文件没有bos.flush();会导致文本文件内容缺失

        socket.shutdownOutput();  //关闭输出流

        //打开输入流接收反馈信息
        BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String str=br.readLine();
        System.out.println(str);

        //关闭通道
        socket.close();
    }
}
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(10086);

        Socket socket=ss.accept();

        //输入流接收文件
        BufferedInputStream bis=new BufferedInputStream(socket.getInputStream());

        //输出流保存文件
        BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("net\\fileout\\11.png"));

        //在输入流读取文件到字节数组再用输出流保存文件
        byte[] bytes=new byte[1024];
        int len;
        while((len=bis.read(bytes))!=-1){
            bos.write(bytes,0,len);
        }
        bos.flush();  //刷新此缓冲的输出流
        //使用outputstream写文件没有bos.flush();会导致文本文件内容缺失

        //打开输出流发送反馈信息
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bw.write("上传成功!");
        bw.newLine();  //写入一个行分隔符
        bw.flush();

        socket.close();
        ss.close();
    }
}

注意:记得关闭输入输出流。

文件名重复

解决上一题文件名重复问题

//解决文件名重复问题
//返回随机生成的UUID,再把其中的"-"去掉
String name= UUID.randomUUID().toString().replace("-","");

//输出流保存文件
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("net\\fileout\\"+name+".png"));

多线程的服务端

想要服务器不停止,能接收很多用户上传的图片。

提示:可以使用循环或者多线程

最优解是循环+多线程

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

public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1", 10086);

        //InputStream读取文件
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\Users\\29163\\Desktop\\java net\\net\\file\\11.png"));

        //创建输出流OutputStream
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());

        //将文件读到字节数组后输出
        byte[] bytes = new byte[1024];
        int len;
        //read(byte[] data);从输入流里面读取若干字节装填到给定的数组里面
        //如果输入流中字节足够则填满,否则只装填前面的部分.返回实际装填长度
        while ((len = bis.read(bytes)) != -1) {  //输入流读入
            bos.write(bytes, 0, len);  //输出流输出
        }
        bos.flush();  //刷新此缓冲的输出流
        //使用outputstream写文件没有bos.flush();会导致文本文件内容缺失

        socket.shutdownOutput();  //关闭输出流

        //打开输入流接收反馈信息
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String str = br.readLine();
        System.out.println(str);

        //关闭通道
        socket.close();
    }
}
import java.io.*;
import java.net.Socket;
import java.util.UUID;

public class MyRunnable implements Runnable {
    Socket socket;

    public MyRunnable(Socket socket) {  //传参
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            //输入流接收文件
            BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());

            //解决文件名重复问题
            //返回随机生成的UUID,再把其中的"-"去掉
            String name = UUID.randomUUID().toString().replace("-", "");

            //输出流保存文件
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\Users\\29163\\Desktop\\java net\\net\\fileout\\" + name + ".png"));

            //在输入流读取文件到字节数组再用输出流保存文件
            byte[] bytes = new byte[1024];
            int len;
            while ((len = bis.read(bytes)) != -1) {
                bos.write(bytes, 0, len);
            }
            bos.flush();  //刷新此缓冲的输出流
            //使用outputstream写文件没有bos.flush();会导致文本文件内容缺失

            //如果不关io,服务端运行的时候文件夹无法正常查看图片的缩略图,Windows自带的照片查看器可以打开图片,wps图片查看器不可以
            bos.close();  //要把输出流关了,在服务端还在运行的时候文件夹才能正常查看图片的缩略图

            //打开输出流发送反馈信息
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bw.write("上传成功!");
            bw.newLine();  //写入一个行分隔符
            bw.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(10086);
        while(true){
            Socket socket = ss.accept();
            new Thread(new MyRunnable(socket)).start();  //一旦接收一个请求就开启一个线程
        }
    }
}

线程池版的服务端

频繁创建线程并销毁非常浪费系统资源,需要用线程池优化。

import test5.MyRunnable;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

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

        //核心线程数量,线程池最大的线程数量,存活时间,时间单位,阻塞队列,线程工厂,任务拒绝策略
        ThreadPoolExecutor pool=new ThreadPoolExecutor(
                3,
                16,
                60,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(2),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );
        while(true){
            Socket socket = ss.accept();
            //new Thread(new MyRunnable(socket)).start();  //一旦接收一个请求就开启一个线程
            pool.submit(new MyRunnable(socket));
        }
    }
}

BS架构模型

接收浏览器消息并打印。

客户端:不需要写。

服务器:接收数据并打印。

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

public class Server {
    public static void main(String[] args) throws IOException {
        //1.创建ServerSocket
        ServerSocket ss=new ServerSocket(10086);

        //2.监听客户端的连接,一但连接返回连接对象
        Socket socket=ss.accept();

        //3.从连接通道中获取输入流
        InputStream is=socket.getInputStream();

        //解决中文乱码,把字节流转换成字符流
        InputStreamReader isr=new InputStreamReader(is);
        //提高读取效率
        BufferedReader br=new BufferedReader(isr);
        int b;
        while((b=br.read())!=-1){
            System.out.print((char)b);
        }

        //4.释放资源
        socket.close();  //关闭连接通道
        ss.close();  //断开连接

    }
}

直接运行客户端程序,用浏览器访问127.0.0.1 :10086,控制台会打印浏览器发送的信息。

浏览器回写数据涉及前端知识。

控制台版聊天室

你可能感兴趣的:(学习笔记,学习,笔记,java)