Java之网络

目的

了解并学习网络,达到能在程序中运用网络的目的

知识点
  • 网络编程:在两台不同的计算机之间数据传递
  • 客户端:与服务器端相对的,为客户提供本地服务的程序,如:手机APP 浏览器 桌面QQ
  • 服务器端:存储/处理数据
  • URL:统一的资源定位
  • 网址表示:当我们打开浏览器随便输入什么,比如:输入android时
    它的网址是https://www.so.com/s?q=android&src=srp&fr=360_wsyjsw_recom3.7.1&ls=sn2321298&lm_extend=ctype%3A4&psid=da1039746140ba0878ed253ad4300c1a
    他们分别代表:
    • http/https:传输协议 TCP/IP协议
    • www.baidu.com:域名 表示一台网络中的电脑
      ipv4 ipv6地址:唯一表示一台网络中的计算机
      32位:四个部分 每个部分是8个字节
      某台电脑的地址172.20.10.15<->www.baidu.com等价
      DNS服务器:域名解析
      www.baidu.com类型的地址解析为对应的ip地址
  • search对应的后台程序文件php java jsp
  • ?表示运行这个程序需要的参数
  • code=android code是服务器端规定的字段
  • &如果有多个参数使用&符号链接
  • ip地址:表示某一台电脑
  • 端口号:用来标识这台电脑上的某一个进程 (80端口)
  • 数据传输:TCP/IP协议
  • TCP:面向连接的(安全的) 比如:打电话
  • UDP:面向无连接的(不安全的,但快) 比如:飞鸽传书
  • 网络中的数据传输:Socket实现->套接字
  • Socket:客户端
  • ServerSocket:服务器端
QQ图片20190822183404.jpg
内容

1.简单实现数据发送
2.手动输入内容发送
3.发送图片
4.实现对聊
5.实现群聊

具体内容
1.简单实现数据发送
     //模拟客户端
    class Client{
        public static void main(String[] args) throws IOException {
            //1.创建用于通信的socket
            //指明谁通信 ip地址 端口号
            Socket socket=new Socket("192.168.43.96",8915);
            //接收服务器端的数据
            BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
             //向服务器端发送数据
            String line= null;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
            //客户端向服务器端发送数据
            PrintStream ps=new PrintStream(socket.getOutputStream());
            ps.println("你好啊");
            socket.shutdownOutput();
         }
     }
    //模拟服务器端
    class Server{
    public static void main(String[] args) throws IOException {
    //1.创建服务器端的serversocket
    ServerSocket ss=new ServerSocket(8915);
    //2.获取连接的客户端的socket
    Socket clientSocket=ss.accept();
    //3.向客户端发送数据
    PrintStream ps=new PrintStream(clientSocket.getOutputStream());
    ps.println("登录成功");
    //输出完毕
    clientSocket.shutdownInput();
    //4.接收客户端发来的数据
    BufferedReader br=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    String line=null;
    while((line=br.readLine())!=null){
        System.out.println(line);
      }
   }
}

先运行服务器端再运行客户端

2.手动输入内容发送
  • 读取数据:服务器读取 客户端读取
    BufferedReader->InputStreamReader->socket.getInputStream()
    读取终端
    BufferedReader->InputStream->System.in
  • 输出:客户端输出 服务器输出
    BufferedWriter->OutputStream->socket.getOutputStream
    PrintStream->socket.Stream()
  • socket 扮演的是客户端
  • ServerSocket扮演的是服务器端

从服务器端输入,将输入的内容发送给客户端

客户端

  class MyClient {
  public static void main(String[] args) {
    //连接客户端的socket
    Socket socket=null;
    try{
        socket=new Socket("192.168.43.96",8662);
        //接收服务器端信息
        BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line=null;
        while ((line=br.readLine())!=null){
            System.out.println(line);
        }

    }catch (IOException e){
        System.out.println("网络出错,请重新输入");
    }finally {
        try{
            socket.close();
         }catch (IOException e){
            e.printStackTrace();
         }
       }
    }
 }

服务器端

  class MyServer{
  public static void main(String[] args) {
    //创建ServerSocket
    try(ServerSocket ss=new ServerSocket(8662)) {
        //监听客户端的连接
        Socket socket=ss.accept();
        //从终端接收数据
        BufferedReader keyin=new BufferedReader(new InputStreamReader(System.in));
        //获取向客户端输出数据的输出流
        PrintStream ps=new PrintStream(socket.getOutputStream());
        String line=null;
        while ((line=keyin.readLine()) !=null){
            //发送给客户端
            ps.println(line);
        }
        //发送给客户端
      } catch (IOException e) {
          e.printStackTrace();
       }
     }
  }
3.发送图片

实现客户端向服务器端发送图片

客户端

  class Client{
  public static void main(String[] args) throws IOException {
    //连接服务器端,获取socket
    Socket socket=new Socket("127.0.0.1",8089);
    //创建服务器端对应的输入流 用于接收服务器发来的数据
    BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    System.out.println(br.readLine());
    //向服务器端发送图片(文件)
    //1.将文件写入到内存
    String path="/Users/Administrator/Desktop/1564315747404.jpeg";
    FileInputStream fis=new FileInputStream(path);
    //2.创建字节流
    BufferedOutputStream bos=new BufferedOutputStream(socket.getOutputStream());
    //3.将文件的内容一点一点的传输给服务器
    byte[] buf=new byte[1024];
    int len=-1;
    while ((len=fis.read(buf))!=-1){
        bos.write(buf,0,len);
    }
    socket.shutdownOutput();
    }
  }

服务器端

  class Server{
  public static void main(String[] args) throws IOException {
    //创建服务器端的ServerSocket
    ServerSocket ss=new ServerSocket(8089);
    //监听客户端连接
    //当有客户端来连接,服务器一直在这里等待
    //当有客户端连接这个服务器,就可以得到对应的server
    Socket socket=ss.accept();
    //创建客户端对应的输出流,用于向这个客户端发送数据
    PrintStream ps=new PrintStream(socket.getOutputStream());
    ps.println("连接成功,可以发送数据了");
    //接收客户端传递过来的图片
    BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
    //文件对应的输出流
    String path="/Users/Administrator/AndroidStudioProjects/javaday1/src/main/java/day12/Medica/1.jpeg";
    FileOutputStream fos=new FileOutputStream(path);
    byte[] buf=new byte[1024];
    int len=-1;
    while ((len=bis.read(buf))!=-1){
        fos.write(buf,0,len);
      }
   }
}
4.实现对聊

使用多线程实现对聊

  • 客户端和服务器端都可以随意的发送内容
  • 从终端输入
  • 客户端
    主线程:接收终端输入 将终端输入发送给服务器端
    子线程;接收服务器端发过来的内容
  • 服务器端
    主线程:接收终端输入 将终端输入发送给客户端
    子线程:接收客户端发过来的数据

客户端

  class Client{
  public static void main(String[] args) throws IOException {
    Socket socket=new Socket("127.0.0.1",8087);
    //主线程处理终端输入发送给服务器端
    BufferedReader keyin=new BufferedReader(new InputStreamReader(System.in));
    PrintStream ps=new PrintStream(socket.getOutputStream());
    //用一个子线程处理服务器端的数据
    new Thread(new ClientThread(socket)).start();
    String line=null;
    while ((line=keyin.readLine())!=null){
        ps.println(line);
    }
  }
}
  • 创建一个子线程处理客户端接收服务器端的数据
  class ClientThread implements Runnable{
  private Socket socket;
  //保存操作的socket对象
  public ClientThread(Socket socket){
    this.socket=socket;
  }
  @Override
  public void run() {
    //获取服务器端的输入流对象
    BufferedReader br= null;
    try {
        br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line=null;
        while((line=br.readLine())!=null){
            System.out.println(line);
        }
    } catch (IOException e) {
        System.out.println("网络连接错误,请重新输入");
        e.printStackTrace();
    }finally {
        try {
            if (br != null) {
                br.close();
            }
            if (socket!=null){
                socket.close();
            }
        }catch (IOException e){

        }
      }
   }
}

服务器端

  class Server{
  public static void main(String[] args) throws IOException {
    ServerSocket ss=new ServerSocket(8087);
    //接收客户端的socket
    Socket socket=ss.accept();
    //创建子线程 处理客户端输入数据
    new ServerThread(socket).start();
    //终端输入流对象
    BufferedReader keyin=new BufferedReader(new InputStreamReader(System.in));
    //客户端输出流
    PrintStream ps=new PrintStream(socket.getOutputStream());
    //读取终端输入,将输入输出给客户端
    String line=null;
    while ((line=keyin.readLine())!=null){
        ps.println(line);
     }
   }
}

创建一个子线程处理服务端接收客户端的数据

  class ServerThread extends   Thread{
  private Socket socket;
  public ServerThread(Socket socket){
    this.socket=socket;

  }

  @Override
  public void run() {
    BufferedReader br=null;
    try {
        br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line=null;
        while ((line=br.readLine())!=null){
            System.out.println(line);
        }
    } catch (IOException e) {
        System.out.println("网络异常,请重新登录");
        e.printStackTrace();
    } finally {
        //关闭输入输出流
        try {
            if (br!=null){
                br.close();
            }
            if (socket!=null){
                socket.close();
            }
        }catch (IOException e){

         }
      }
   }
}
5.实现群聊

客户端

  class Client{
  public static void main(String[] args) throws IOException {
    Socket socket=new Socket("127.0.0.1",5001);
    //主线程处理终端输入发送给服务器端
    BufferedReader keyin=new BufferedReader(new InputStreamReader(System.in));
    PrintStream ps=new PrintStream(socket.getOutputStream());
    //用一个子线程处理服务器端的数据
    new Thread(new ClientThread(socket)).start();
    String line=null;
    while ((line=keyin.readLine())!=null){
        ps.println(line);
     }

  }
}
  class ClientThread implements Runnable{
  private Socket socket;
  //保存操作的socket对象
  public ClientThread(Socket socket){
      this.socket=socket;
  }
  @Override
  public void run() {
    //获取服务器端的输入流对象
    BufferedReader br= null;
    try {
        br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line=null;
        while((line=br.readLine())!=null){
            System.out.println(line);
        }
    } catch (IOException e) {
        System.out.println("网络连接错误,请重新输入");
        e.printStackTrace();
    }finally {
        try {
            if (br != null) {
                br.close();
            }
            if (socket!=null){
                socket.close();
            }
          }catch (IOException e){

          }
        }
     }
 }

服务器端

  class Server{
  //保存每一个连接过来的对象
  public static ArrayList<Socket> sockets=new ArrayList<>();
  public static void main(String[] args) throws IOException {
      ServerSocket ss=new ServerSocket(5001);
    //不停的等待客户端来连接数据
    while (true) {
        Socket socket = ss.accept();
        //当有客户端过来了就保存
        sockets.add(socket);
        //开启一个线程处理客户端的输入
        new ServerThread(socket).start();
        }
     }
  }
  class ServerThread extends Thread{
  private Socket socket;
  public ServerThread(Socket socket){
      this.socket=socket;

  }

  @Override
  public void run() {
      BufferedReader br=null;
      try {
        br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line=null;
        while ((line=br.readLine())!=null){
            //群发消息
            //遍历Server维护的每一个数组
            for (Socket s:Server.sockets){
                //向socket对应的客户端发送消息
                PrintStream ps=new PrintStream(s.getOutputStream());
                ps.println(line);
            }
        }
    } catch (IOException e) {
        System.out.println("网络异常,请重新登录");
        e.printStackTrace();
    } finally {
        //关闭输入输出流
        try {
            if (br!=null){
                br.close();
            }
            if (socket!=null){
                socket.close();
            }
        }catch (IOException e){

         }
      }
   }
}
小结

慢慢地,我们正在将前面学过的知识运用到不同的场景,实现知识融合,这是很好的将短期记忆转化成长期记忆的方法,不仅仅学习了新知识,还将学过的一并实现。我们一起回想加深对其的理解。我相信,编程这条路虽难,但越难的东西越能激起人的挑战欲,让我进步,我会继续加油的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • 计算机网络概述 网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输。 按照计算机网络的定义,通过一定...
    蛋炒饭_By阅读 1,209评论 0 10
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,084评论 1 32
  • Java知识点1、==和equals的区别基本类型比较==比较内容 equals比较地址值引用类型比较==比较地址...
    压抑的内心阅读 586评论 0 0
  • InetAddress DatagramPacket、DatagramSocket ServerSocket、So...
    如果仲有听日阅读 288评论 0 0
  • 1.网络编程1.1计算机网络概述网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输。按照计算机网络的...
    任振铭阅读 421评论 0 1