javaday17

目录                       

1     网络. 1

1.1   Socket 通信. 1

1.2       服务器端. 1

1.3       客户端. 1

1.4       超时. 1

练习1   网络. 1

1.5       阻塞操作. 1

1.6       服务器端的线程模型. 1

练习2   回声. 1

练习3   聊天室. 1

1   回顾

l  HashMap

n  key.hashCode() 得到哈希值,用哈希值来计算下标 i

n  键值对封装成 Enyry 实例放入 i 位置

u  空位置,直接放入

u  有数据,依次用key.equals()方法比较是否相等

l  找到相等的键,覆盖值

l  没有相等的键,用链表连接在一起

u  负载率,加载因子到0.75 (数据量/容量)

l  新建翻倍容量的新数组

l  所有数据重新执行哈希运算放入新数组

u  jdk1.8

l  链表长度到8,把链表转成红黑树

l  树上的数据减少到6,转回成链表

2   网络

在物理网络的基础上,建立抽象的连接

win + r, 输入 cmd

输入命令:

ipconfig

 

ping 192.168.21.xxx

如果ping不通,要关闭防火墙

开始---搜索防火墙

 

2.1 Socket 通信

Socket - 插头

Socket - 网络套接字

l  通过 ip 地址,两台主机可以互相找到对象

l  在两台主机上,各选择一个端口号

n  端口是独占的

n  0到1024是一些常见服务的默认端口

u  http 80

u  https 443

u  ftp 21

u  ...

n  5万以后,是系统保留端口用,来自动分配

n  我们选择端口要选择 1024到5万之间的端口号

2.2     服务器端

被动等待客户端发起连接

ServerSocket 在服务器端,选择一个端口号, 在指定端口上等待客户端发起连接

ServerSocket ss = new ServerSocket(8000);

等待客户端发起连接,建立连接通道,并返回连接通道的服务器端插头对象

Socket s = ss.accept();

2.3     客户端

主动去连接服务器

Socket s = new Socket(ip, port);

取出双向的流

InputStream in = s.getInputStream();

OutputStream out = s.getOutputStream();

2.4     超时

socket.setSoTimeout(毫秒值)

设置接收数据,等待超时时长,超时会出现 SocketTimeoutException

练习1  网络

package day17;

 

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

 

public class Server1 {

public static void main(String[] args) throws Exception {

    ServerSocket ss = new ServerSocket(8000);

    System.out.println(

     "服务已经在 8000 端口上启动");

    //暂停等待客户端发起连接

    System.out.println("等待客户端连接");

    Socket s = ss.accept();

    System.out.println("客户端已连接");

    //从插头对象,获取输入流和输出流

    InputStream in = s.getInputStream();

    OutputStream out = s.getOutputStream();

    /*

     * 通信协议,通信流程,数据格式

     *

     *     服务器端:

     *       1. 接收 "hello"

     *       2. 发送 "world"

     */

    for (int i = 0; i < 5; i++) {

        char c = (char) in.read();

        System.out.print(c);

    }

   

    out.write("world".getBytes());

    out.flush(); //刷出内存缓存

   

    s.close();//断开连接

    ss.close();//停止服务,释放端口

   

}

}

Client1

package day17;

 

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

 

public class Client1 {

public static void main(String[] args) throws Exception {

    Socket s = new Socket("旁边同学ip", 8000);

    InputStream in = s.getInputStream();

    OutputStream out = s.getOutputStream();

    /* 客户端:

     *    1. 发送 "hello"

     *    2. 接收 "world"

     */

    out.write("hello".getBytes());

    out.flush(); //刷出内存缓存

    for (int i = 0; i < 5; i++) {

        char c = (char) in.read();

        System.out.print(c);

    }

    s.close();

}

}

2.5     阻塞操作

ss.accept()

暂停,等待客户端发起连接

in.read()

对方不发送数据,暂停,死等数据

2.6     服务器端的线程模型

 

练习2  回声

客户端发送到服务器的数据,原封不动的发回客户端

EchoServer

package day17;

 

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

 

public class EchoServer {

public void launch() {

    new Thread() {

        @Override

        public void run() {

           try {

              ServerSocket ss = new ServerSocket(8000);

              System.out.println("服务已在 8000 端口上启动");

              while(true) {

                 System.out.println("等待下一个客户端连接");

                 Socket s = ss.accept();

                 System.out.println("客户端已连接");

                 TongXinThread t = new TongXinThread(s);

                 t.start();

              }

           } catch (Exception e) {

              System.out.println(

               "无法在 8000 端口上启动服务,或服务已停止");

           }

        }

    }.start();

}

 

 

class TongXinThread extends Thread {

    Socket s;

    public TongXinThread(Socket s) {

        this.s = s;

    }

    @Override

    public void run() {

        /*

         * 通信协议,流程和格式

         * UTF-8编码的字符串,

         * 每段字符串末尾添加换行

         *

         * BR--ISR--网络输入流

         * PW--OSW--网络输出流

         */

       

        try {

           BufferedReader in =

            new BufferedReader(

            new InputStreamReader(

            s.getInputStream(), "UTF-8"));

           PrintWriter out =

            new PrintWriter(

            new OutputStreamWriter(

            s.getOutputStream(),"UTF-8"));

           String line;

           while((line = in.readLine()) != null) {

              out.println(line);

              out.flush();

           }

           //断开

        } catch (Exception e) {

           //断开

        }

       

        System.out.println("一个客户端端已断开");

       

    }

}

 

 

public static void main(String[] args) {

    EchoServer s = new EchoServer();

    s.launch();

}

}

EchoClient

package day17;

 

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.io.UnsupportedEncodingException;

import java.net.Socket;

import java.util.Scanner;

 

public class EchoClient {

public static void main(String[] args) throws Exception {

    Socket s = new Socket("找一个人启动服务器", 8000);

    BufferedReader in =

     new BufferedReader(

     new InputStreamReader(

     s.getInputStream(), "UTF-8"));

    PrintWriter out =

     new PrintWriter(

     new OutputStreamWriter(

     s.getOutputStream(),"UTF-8"));   

    while(true) {

        System.out.print("输入:");

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

        out.println(str);

        out.flush();

        String echo = in.readLine();

        System.out.println("回声:"+echo);

        System.out.println("-----------------");

    }

}

}

练习3  聊天室

ChatServer

package day17;

 

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.ArrayList;

 

public class ChatServer {

 

private ArrayList<TongXinThread> list =

        new ArrayList<>();

 

public void launch() {

    //启动服务线程

    new Thread() {

        @Override

        public void run() {

           try {

              ServerSocket ss = new ServerSocket(8000);

              System.out.println("聊天室服务器已启动");

              while(true) {

                 Socket s = ss.accept();

                 TongXinThread t =

                  new TongXinThread(s);

                 t.start();

              }

           } catch (Exception e) {

              System.out.println(

               "服务无法在 8000 端口上启动,或服务已经停止");

           }

        }

    }.start();

}

 

class TongXinThread extends Thread {

    Socket s;

    BufferedReader in;

    PrintWriter out;

    private String name;

    public TongXinThread(Socket s) {

        this.s = s;

    }

   

    public void send(String msg) {

        out.println(msg);

        out.flush();

    }

   

    public void sendAll(String msg) {

        synchronized (list) {

           for (TongXinThread t : list) {

              t.send(msg);

           }

        }

    }

   

    @Override

    public void run() {

        try {

           //UTF-8, 换行

           in = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"));

           out = new PrintWriter(new OutputStreamWriter(s.getOutputStream(),"UTF-8"));            

           //接收客户端的昵称

           this.name = in.readLine();

           //把当前通信线程实例,加入集合

           synchronized (list) {

              list.add(this);

           }

           //发送欢迎信息

           send("欢迎进入激情聊天室");

           //群发上线消息

           sendAll(name+"进入了聊天室,在线人数:"+list.size());

          

           String line;

           while((line = in.readLine()) != null) {

              sendAll(name+"说:"+line);

           }

           //断开

        } catch (Exception e) {

           //断开

        }

        //删除当前通信线程实例

        synchronized (list) {

           list.remove(this);

        }

        //群发离线消息

        sendAll(name+"离开了聊天室,在线人数:"+list.size());

       

       

    }

}

 

 

 

 

public static void main(String[] args) {

    ChatServer s = new ChatServer();

    s.launch();

}

}

ChatClient

package day17;

 

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.net.Socket;

import java.util.LinkedList;

import java.util.Scanner;

 

public class ChatClient {

private Socket s;

private BufferedReader in;

private PrintWriter out;

private String name;

private LinkedList<String> list = new LinkedList<>();

private boolean flag; //开关

 

public void launch() {

    try {

        s = new Socket("192.168.21.61", 8000);

        in = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"));

        out = new PrintWriter(new OutputStreamWriter(s.getOutputStream(),"UTF-8"));              

        //昵称

        System.out.print("起一个昵称: ");

        name = new Scanner(System.in).nextLine();

        out.println(name);

        out.flush();

       

        //接收线程

        new Thread() {

           @Override

           public void run() {

              receive();

           }

        }.start();

       

        //输入线程

        new Thread() {

           @Override

           public void run() {

              input();

           }

        }.start();

       

        //打印线程

        new Thread() {

           @Override

           public void run() {

              print();

           }

        }.start();

       

    } catch (Exception e) {

        System.out.println("无法连接聊天室服务器");

        e.printStackTrace();

    }

}

 

protected void print() {

    while(true) {

        synchronized (list) {

           while (list.isEmpty() || flag) {

              try {

                 list.wait();

              } catch (InterruptedException e) {

              }

           }

           String msg = list.removeFirst();

           System.out.println(msg);

        }

    }

}

 

protected void input() {

    System.out.println("按回车输入聊天内容");

   

    while(true) {

        new Scanner(System.in).nextLine();

        flag = true;//打开开关

       

        System.out.print("输入聊天内容:");

        String s = new Scanner(System.in).nextLine();

        out.println(s);

        out.flush();

       

        flag = false;//关闭开关

        //通知打印线程可以继续打印

        synchronized (list) {

           list.notify();

        }

    }

}

 

protected void receive() {

    try {

        String line;

        while((line = in.readLine()) != null) {

           synchronized (list) {

              list.add(line);

              //通知打印线程已经有数据可以打印了

              list.notify();

           }

        }

    } catch (Exception e) {

    }

    System.out.println("已经与服务器断开连接");

}

 

public static void main(String[] args) {

    ChatClient c = new ChatClient();

    c.launch();

}

}

 

 

猜你喜欢

转载自www.cnblogs.com/ou-yang/p/12957680.html
今日推荐