Socket就是一个Java类,底层协议TCP/UDP
    这个类的目的就是底层通过协议进行两端的关联

    需要深入了解的是TCP协议(特点:三次握手、四次挥手)
    其底层是基于字节型流执行操作

    1、利用Socket进行连接
    TCP协议
    服务端 ServerSocket
    客户端 Socket
    2、如何利用流进行通信
    获取字节流进行传输
    输出 OutputStream os =socket.getInputStream();
    输入 InputStream is = socket.getOutputStream();
    为了传递字符方便 可以做一些包装
    PrintWriter pw = new PrintWriter(os); 字符输出打印流
    pw.priintln(“ “);//可以发送一行信息过去
    InputStreamReader isr = new InputStreamReader(is); 字节字符转换流
    //可以将字节型的流转换成字符型
    BufferedReader br = new BufferedReader(isr); 高级字符输入流
    //可以一次读取一行
    3、可能出现的问题
    3.1)SocketException:Connection reset ——> 这是一个说明性异常,我在等待接收对方信息时,对方下线了
    异常的原因:
    一端退出,但退出时并未关闭该连接
    另一端如果在从连接中读数据则抛出该异常(Connection reset)
    简单的说就是在连接断开后的读和写操作引起的。
    3.2)发送和接收都需要顺序
    发送端和接受端同一时刻只能有一端在传送数据
    为了解决收发顺序问题 —-> 可以利用线程
    实现多线程方式
    服务端两个线程,一个接收,一个发送
    客户端两个线程,一个接收,一个发送
    3.3)有了线程之后,两端可以进行自由的通信
    但是真正的聊天软件,服务端是不会说话的,应该是客户端和客户端进行交流
    能不能有多个客户端连接同一个服务器?
    如果能,怎么连接?
    如果连接了,客户端有很多个,服务端只有一个,服务端需要存储好多个客户端的socket,怎么存?—-> 集合
    Map String类对应客户的id号,domain中存储的是客户的id号和socket对象
    所以当客户端之间相互通信时,服务端相当于一个中转,负责读取客户端的消息,转发给另一个客户端

    服务端:

    1. /**
    2. * 这是服务端
    3. */
    4. public class Server {
    5. public static void main(String[] args){
    6. //new对象时底下有红线通常有三种情况
    7. //1.抽象类 或者 接口 不让new
    8. //2.需要传参数
    9. //3.编译时异常 可能需要捕获异常
    10. try {
    11. System.out.println("---------server start---------");
    12. //1.创建服务器对象ServerSocket 需要给参数 即开放的端口号
    13. //端口号 0 - 65535 一般不选3000以下的 被占用了
    14. ServerSocket server = new ServerSocket(8888);
    15. //2.等待客户端连接
    16. Socket socket = server.accept();//同意连接 如果没有人来 就一直等
    17. //若能成功获取到这个socket类 证明连接成功
    18. //连接成功后 服务端可以对客户端说一句话
    19. //通过客户端获取一个字节型输出流
    20. OutputStream os = socket.getOutputStream();
    21. //用字节流写文字不方便 可将字节流包装成字符流 为了发送一行文字
    22. PrintWriter writer = new PrintWriter(os);
    23. //发送文字
    24. writer.println("连我干嘛?");
    25. writer.flush();
    26. //服务端接收客户端信息
    27. //获取输入流
    28. InputStream is = socket.getInputStream();
    29. //包装成字符型
    30. InputStreamReader isr = new InputStreamReader(is);
    31. //再包装 让其可以读一行
    32. BufferedReader br = new BufferedReader(isr);
    33. String value = br.readLine();
    34. System.out.println(value);
    35. } catch (IOException e) {
    36. e.printStackTrace();
    37. }
    38. }
    39. }

    客户端:

    1. /**
    2. * 这是客户端
    3. */
    4. public class Client {
    5. public static void main(String[] args){
    6. try {
    7. System.out.println("----client start----");
    8. //1.主动发起对服务器的访问
    9. //需要两个参数 第一个是服务器的地址 第二个是端口号
    10. Socket socket = new Socket("localhost",8888);
    11. //若能成功创建socket对象 则与服务器连接成功
    12. //连接成功后服务器发了一句话过来 客户端须接受
    13. //获取一个输入流
    14. InputStream is = socket.getInputStream();
    15. //将字节型流转换成字符型
    16. InputStreamReader inr = new InputStreamReader(is);
    17. //将字符流再包装一次 目的是为了一次可以读取一行 跟服务端统一
    18. BufferedReader reader = new BufferedReader(inr);
    19. //读取一行数据
    20. String value = reader.readLine();
    21. System.out.println(value);
    22. //客户端给服务端说话
    23. //获取一个输出流
    24. OutputStream os = socket.getOutputStream();
    25. //包装成字符型
    26. PrintWriter pw = new PrintWriter(os);
    27. pw.println("哈哈哈 连你咋地?");
    28. pw.flush();
    29. } catch (IOException e) {
    30. e.printStackTrace();
    31. }
    32. }
    33. }