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基础查缺补漏01

    某些点会在不远的将来深挖。 >>是逻辑右移,>>>是算术右移 JDK6 可以使用Console.readPassword从控制台中读取密码,用户输入的过程中密码是不可见的。…

    2019年11月26日
    0600
  • JUC包下的线程协作计数CountDownLatch及CyclicBarrier

    CountDownLatch 概述 用来进行线程同步协作,等待所有线程完成倒计时。 其中构造参数用来初始化等待计数值,await() 用来等待计数归零,countDown() 用来…

    Java 2020年2月6日
    02070
  • Java基础查缺补漏05

    继续我的复习刷题 可以有和类名同名的函数 题目: JAVA中,下列语句哪一个正确() A. class中的constructor不可省略B. constructor必须与class…

    Java 2020年5月29日
    0140
  • 深入理解java虚拟机第三版读书笔记11

    以下是第十一章 后端编译与优化的内容 把Class文件转换成与本地基础设施(硬件指令集、操作系统)相关的二进制机器码可以视为整个编译过程的后端。 最近几年提前编译也开始兴起,我们在…

    2020年1月27日
    0300
  • JUC包下的信号量Semaphore

    概述 信号量,用来限制能同时访问共享资源的线程上限。 public static void main(String[] args) { // 1. 创建 semaphore 对象 …

    Java 2020年2月6日
    0200
  • Java中的四种内部类

    我发现最近真是越来越没有东西写了。。。不可能天天学习新知识啊,最近在复习阶段了,复习的东西大多数是博客里写过的/(ㄒoㄒ)/ 复习Java基础的时候认真看了一下Java的内部类,这…

    Java 2020年5月23日
    0100
  • String s = new String("123");创建了几个String对象?

    提要 最近复习看到一道题目很有意思啊: String s = new String("123"); 问这样一行代码创建了几个String对象? 乍一看我其实以为和JDK的版本有关系…

    Java 2020年5月24日
    0580
  • Java基础查缺补漏02

    哈哈我其实没有想到这个系列真会有续集,上次写完01以后以为不会再写下去了,没想到最近牛客网刷题有些题目还是挺纠结的,这里补一补 构造器能带哪些修饰符 题目: Which of th…

    Java 2020年5月25日
    080
  • Collection接口研究

    以下内容基于jdk1.8 接口Collection分析 img 该接口实现了接口Iterable 方法: int size(); 返回元素的个数 boolean isEmpty()…

    2019年11月13日
    0100
  • LinkedHashMap源码分析

    总结 总结放前面防止太长不看: LinkedHashMap继承自HashMap,为Entry额外维护了两个属性:before和after,可以按照节点的插入顺序或者访问顺序为Ent…

    Java 2020年2月19日
    0550

发表回复

登录后才能评论