Java网络套接字Socket编程

Socket概述

Socket,译作网络套接字,是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。网络套接字与一个应用进程(ip和端口号)绑定。

Socket与ServerSocket

Socket与ServerSocket是Java中Socket编程的常用类,一般分别指客户端和服务端的socket。

工作流程:

  • 服务端bind():绑定端口
  • 服务端accept():等待客户端建立连接
  • 客户端connect():连接到服务端
  • 双方进行IO操作
  • 服务端和客户端close():关闭socket连接

代码示例

实现一个客户端给服务端发送数据,服务端按原数据返回的程序。

第一版

服务端:

public class Server {
    public static void main(String[] args) {
        final int DEFAULT_PORT = 8888;
        ServerSocket serverSocket = null;

        // 绑定监听端口
        try {
            serverSocket = new ServerSocket(DEFAULT_PORT);
            System.out.println("启动服务器,监听端口"+DEFAULT_PORT);
            while (true){
                Socket socket = serverSocket.accept();//等待客户端连接,阻塞
                System.out.println("客户端["+socket.getPort()+"]已连接");
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(socket.getInputStream())
                );
                BufferedWriter writer = new BufferedWriter(
                        new OutputStreamWriter(socket.getOutputStream())
                );
                // 读取客户端发送的消息
                String msg = reader.readLine();
                if(msg!=null){
                    System.out.println("客户端["+socket.getPort()+"]: " + msg);
                    //回复客户发送的消息
                    writer.write("服务器: "+msg+"\n");
                    writer.flush();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

客户端:(运行于同一台主机上)

public class Client {
    public static void main(String[] args) {
        final String DEFAULT_SERVER_HOST="127.0.0.1";
        final int DEFAULT_PORT = 8888;
        Socket socket = null;
        BufferedWriter writer = null;

        try {
            //创建socket
            socket = new Socket(DEFAULT_SERVER_HOST,DEFAULT_PORT);

            //创建IO流
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(socket.getInputStream())
            );
            writer = new BufferedWriter(
                    new OutputStreamWriter(socket.getOutputStream())
            );

            // 等待用户输入信息
            BufferedReader consoleReader = new BufferedReader(
                    new InputStreamReader(System.in)
            );
            String input = consoleReader.readLine();

            //发送消息给服务器
            writer.write(input+"\n");
            writer.flush();

            //读取服务器返回的消息
            String msg = reader.readLine();
            System.out.println(msg);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(writer!=null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

第二版

一个客户端可以反复发送消息,直到输入quit退出

客户端:

public class Client {
    public static void main(String[] args) {
        final String QUIT = "quit";
        final String DEFAULT_SERVER_HOST="127.0.0.1";
        final int DEFAULT_PORT = 8888;
        Socket socket = null;
        BufferedWriter writer = null;

        try {
            //创建socket
            socket = new Socket(DEFAULT_SERVER_HOST,DEFAULT_PORT);

            //创建IO流
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(socket.getInputStream())
            );
            writer = new BufferedWriter(
                    new OutputStreamWriter(socket.getOutputStream())
            );

            // 等待用户输入信息
            BufferedReader consoleReader = new BufferedReader(
                    new InputStreamReader(System.in)
            );
            while(true){
                String input = consoleReader.readLine();
                if(input.equals(QUIT)) break;
                //发送消息给服务器
                writer.write(input+"\n");
                writer.flush();

                //读取服务器返回的消息
                String msg = reader.readLine();
                System.out.println(msg);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(writer!=null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

服务端:

public class Server {
    public static void main(String[] args) {
        final int DEFAULT_PORT = 8888;
        ServerSocket serverSocket = null;

        // 绑定监听端口
        try {
            serverSocket = new ServerSocket(DEFAULT_PORT);
            System.out.println("启动服务器,监听端口"+DEFAULT_PORT);
            while (true){
                Socket socket = serverSocket.accept();//等待客户端连接,阻塞
                System.out.println("客户端["+socket.getPort()+"]已连接");
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(socket.getInputStream())
                );
                BufferedWriter writer = new BufferedWriter(
                        new OutputStreamWriter(socket.getOutputStream())
                );

                String msg = null;
                while((msg = reader.readLine())!=null){
                    // 读取客户端发送的消息
                    System.out.println("客户端["+socket.getPort()+"]: " + msg);
                    //回复客户发送的消息
                    writer.write("服务器: "+msg+"\n");
                    writer.flush();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/java%e7%bd%91%e7%bb%9c%e5%a5%97%e6%8e%a5%e5%ad%97socket%e7%bc%96%e7%a8%8b/

(0)
彭晨涛彭晨涛管理者
上一篇 2020年2月4日
下一篇 2020年2月5日

相关推荐

  • 深入理解java虚拟机第三版读书笔记05

    续深入理解java虚拟机第三版读书笔记04 HotSpot的算法细节实现 根节点枚举 如何高效的找出所有GC Roots? 迄今为止,所有收集器在根节点枚举这一步骤时都是必须暂停用…

    2020年1月12日
    0570
  • NIO零拷贝与其系统函数调用

    本文参考资源: Java NIO学习笔记四(零拷贝详解)Java拿笔小星的博客-CSDN博客 关于Buffer和Channel的注意事项和细节 ByteBuffer不止可以存取by…

    2020年3月14日
    0490
  • PriorityQueue源码分析

    总结 总结放前面防止太长不看: PriorityQueue是个最小堆,如果要改变排序顺序只能重写比较器传入构造方法。 内部元素要么实现Comparable接口,要么传入比较器进行比…

    Java 2020年2月10日
    0260
  • 按键排序的Map-TreeMap源码分析

    总结 总结放前面(这篇挺短的)1. TreeMap基于红黑树实现,可以对Map中的key排序2. 它的排序和定位需要依赖比较器或实现 Comparable 接口,也因此不需要key…

    Java 2020年2月16日
    0130
  • Java之UDP编程

    DatagramSocket概述 上次在Java网络套接字Socket编程那篇博客里只写了Socket和ServerSocket,即TCP通信,这次来补充一下UDP通信。 和Soc…

    Java 2020年3月11日
    0810
  • 阻塞队列BlockingQueue详解

    阻塞队列是生产者消费者模式的经典体现。 我们在曾在Java线程池详解中自己实现过一个阻塞队列,这篇文章我们来研究一下JDK中的阻塞队列: BlockingQueue接口主要方法 抛…

    Java 2020年2月14日
    0580
  • Java中的File类以及IO流

    File 类 概述 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。 构造方法 public File(String path…

    Java 2020年2月4日
    0150
  • AbstractCollection默认集合类

    AbstractCollection用于实现基本的Collection结构,提供给普通用户继承使用。也是JDK集合类的父类,部分方法是没有被重载的。 相比Collection接口并…

    Java 2019年11月18日
    0100
  • NIO、BIO模型对比实现文件的复制

    NIO特点 使用Channel代替Stream,是双向的 使用Selector监控多条Channel 可以在一个线程里处理多个Channel I/O Channel和Buffer …

    Java 2020年2月7日
    0180
  • Java反射机制和动态代理详解

    反射 概念 反射机制: 指的是可以于运行时加载、探知、使用编译期间完全未知的类。 程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个已加载的类,都能够知道这个类的所有属性…

    Java 2020年2月15日
    0570

发表回复

登录后才能评论