【Java】Socket

跨平台(Windows+Linux)的Socket通讯程序(一)—底层封装 【摘要】编写Socket通讯程序是一个老话题。本文重点介绍Windows平台和Linux平台Socket通讯的不同,采用C++,编制了一个简单的跨平台的Socket通讯库。 一、Socket通讯的基础知识 Socket通讯是两个计算机之间最基本的通讯方法,有TCP和UDP两种协议。关于这两种协议的区别,不少文章已有详述,这里,稍微总结一下: 1.TCP是面向连接的,是“流”式的,意即通讯两端 阅读详情

简单学学Java网络编程——Socket

1. 前言

Java 基础 之 网络编程。

学习Socket的必要性

  1. 实现网络通信:Socket编程是实现网络通信的基础。通过Socket,可以在不同的计算机之间建立连接,实现数据的传输和通信。
  2. 客户端-服务器模型:Socket编程是构建客户端-服务器模型的关键。可以使用Socket在客户端和服务器之间建立连接,并进行双向通信,实现数据的发送和接收。
  3. 跨平台性:Java Socket编程是跨平台的,这意味着我们可以在不同的操作系统上使用相同的代码进行网络通信。这使得Socket编程在构建分布式系统和跨网络通信时非常有用。
  4. 网络安全:了解Socket编程可以帮助我们理解网络安全的基本原理和机制。

学习目标
简单学习基本的 Java Socket 使用方式。为日后深入理解Tomcat等服务器原理打下基础。

对于我们一线基层开发而言,工作中直接用到Socket的机会很少,因此本文可用当作拓展小知识阅读。

学习基础
科班必备: 408 之一 《计算机网络》

参考教程
how2j的Java教程:https://how2j.cn/

注:本文大部分代码搬运自参考教程,请读者按需食用。

2.Java Socket

2.1 获取 ip

获取本机IP

public static void main(String[] args) throws UnknownHostException {
        // get local socket ip
        InetAddress inetAddress = InetAddress.getLocalHost();
        String ip = inetAddress.getHostAddress();
        System.out.println("local ip: " + ip);
    }

执行 ping 命令

public static void main(String[] args) throws IOException {
        Process p = Runtime.getRuntime().exec("ping 127.0.0.1");
        // using buff reader to read the result
        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            if (line.length() > 0) {
                sb.append(line);
            }
        }
        System.out.println("ping finished");
        System.out.println(sb);
}

若是在 Windows OS 本地执行 这个代码,有可能会因为编码问题初学乱码,但没有关系,结果中出现 TTS 就说明本次ping通了。

根据上述的例子,我们已经学习了如何通过Java代码获取本地 ip 以及执行 ping 操作。接下来我们做一个练习:

判断当前网段有多少能ping通的ip地址:

public static void main(String[] args) throws IOException, InterruptedException {
        InetAddress host = InetAddress.getLocalHost();
        String ip = host.getHostAddress();
        String ipRange = ip.substring(0, ip.lastIndexOf("."));
        System.out.println("local ip: " + ip);
        System.out.println("ip range: " + ipRange);

        List<String> ips = Collections.synchronizedList(new ArrayList<>());
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                10,
                15,
                60,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>());
        AtomicInteger number = new AtomicInteger();
        for (int i = 1; i < 255; i++) {
            String testIp = ipRange + "." + i;
            threadPool.execute(() -> {
                boolean reachable = isReachable(testIp);
                if (reachable) {
                    ips.add(testIp);
                }

                synchronized (number){
                    System.out.println("check ip: " + testIp + ", reachable: " + reachable + ", current: " + number.incrementAndGet());
                }
            });
        }

        threadPool.shutdown();
        if(threadPool.awaitTermination(1, TimeUnit.HOURS)){
            for (String s : ips) {
                System.out.println("find access ip: " + s);
                System.out.println(s);
            }
            System.out.println("finished, find access ips: " + ips.size());
        }

    }

    /**
     * find access ips
     */
    private static boolean isReachable(String ip){
        String success = "TTL";
        try {
            boolean reachable = false;
            Process p = Runtime.getRuntime().exec("ping -n 1 " + ip);
            BufferedReader br = new BufferedReader(new java.io.InputStreamReader(p.getInputStream()));
            String line;
            StringBuilder sb = new StringBuilder();
            while ((line = br.readLine()) != null) {
                if (line.length() > 0) {
                    sb.append(line+"\r\n");
                }
            }
            // if contains TTL then reachable
            if(sb.toString().contains(success)){
                reachable = true;
            }
            br.close();
            return reachable;
        }catch (IOException e){
           e.printStackTrace();
           return false;
        }

}

2.2 Socket 套接字

本文参考的教程直接用Socket简单实现了一个Server和Client,通过写这两个简单的Servier 和 Client, 我们可以了解到Socket的基本用法:

Server

public class Server {
    public static void main(String[] args) {

        try {
            ServerSocket ss = new ServerSocket(8888);
            System.out.println("server started, waiting for client...");
            Socket s = ss.accept();
            s.close();
            ss.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

Client

public class Client {
    public static void main(String[] args) {
        try {
            Socket s = new Socket("127.0.0.1",8888);
            System.out.println(s);
            s.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

Socket接发消息

Client :

public static void main(String[] args) {
        try {
            Socket s = new Socket("127.0.0.1",8888);
            System.out.println(s);
            OutputStream os = s.getOutputStream();
            os.write(97);
            os.close();
            s.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

Server :

public static void main(String[] args) {

        try {
            ServerSocket ss = new ServerSocket(8888);
            System.out.println("server started, waiting for client...");
            Socket s = ss.accept();
            InputStream is = s.getInputStream();
            int msg = is.read();
            System.out.println("msg from client: " + msg);
            is.close();
            s.close();
            ss.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

3. 练习

如果是为了应付课内考试的同学,可参考以下代码进行练习。

双工Demo
基于上面章节列举的Server、Client demo,实现双工demo:

ublic class DoubleClient {
    public static void main(String[] args) {
        try {
            Socket s = new Socket("127.0.0.1", 8888);
            OutputStream os = s.getOutputStream();
            DataOutputStream dos = new DataOutputStream(os);
            InputStream is = s.getInputStream();
            DataInputStream dis = new DataInputStream(is);

            while (true){
                Scanner sc =  new Scanner(System.in);
                System.out.print("client says: ");
                String str = sc.next();
                dos.writeUTF(str);
                if("bye".equals(str)) {
                    break;
                }
                String msg = dis.readUTF();
                System.out.println("server says: " + msg);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

public class DoubleServer {
    public static void main(String[] args) {
        try {
            ServerSocket ss = new ServerSocket(8888);
            System.out.println("server is running...");
            Socket s = ss.accept();
            System.out.println("client is connected...");
            InputStream is = s.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            OutputStream os = s.getOutputStream();
            DataOutputStream dos = new DataOutputStream(os);

            while (true){
                String msg = dis.readUTF();
                System.out.println("client says: " + msg);
                if("bye".equals(msg)) {
                    break;
                }
                Scanner sc = new Scanner(System.in);
                System.out.print("server says: ");
                String str = sc.next();
                dos.writeUTF(str);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

多线程聊天
结合多线程,做一个小练习

发送线程:

public class SendThread extends Thread {
    private Socket s;

    public SendThread(Socket s) {
        this.s = s;
    }


    public void run(){
        try {
            OutputStream os = s.getOutputStream();
            DataOutputStream dos = new DataOutputStream(os);

            while(true){
                Scanner sc = new Scanner(System.in);
                String str = sc.next();
                dos.writeUTF(str);
            }
        } catch (IOException e) {

            e.printStackTrace();
        }

    }
}

接收线程:

public class AcceptThread extends Thread {
    private Socket s;

    public AcceptThread(Socket s) {
        this.s = s;
    }

    public void run() {
        try {
            InputStream is = s.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            while (true) {
                String msg = dis.readUTF();
                System.out.println(msg);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

服务端:

public class ThreadServer {
    public static void main(String[] args) {
        try {
            ServerSocket ss = new ServerSocket(8888);
            System.out.println("监听在端口号:8888");
            Socket s = ss.accept();
            //启动发送消息线程
            new SendThread(s).start();
            //启动接受消息线程
            new AcceptThread(s).start();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

客户端:

public class ThreadClient {
    public static void main(String[] args) {
        try {
            Socket s = new Socket("127.0.0.1", 8888);
            // 启动发送消息线程
            new SendThread(s).start();
            // 启动接受消息线程
            new AcceptThread(s).start();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4. 总结

本文介绍了 Socket 套接字的基本使用,实际工作中用得少,但是也是Java学习的必经之路。本文记录了一些节选自参考教程的练习,读者可按需选用。

【Java TCP/IP Socket】Socket编程大合集 为了方便各位网友学习以及方便自己复习之用,将Java TCP/IP Socket编程系列内容按照学习顺序总结如下: 【Java TCP/IP Socket】Java TCP Socket程编程 【Java TCP/IP Socket】Java UDP Socket编程 【Java TCP/IP Socket】应用程序协议中消息的成帧与解析 【Java TCP/IP Socket】构建和解析自定义协议消息 【Java TCP/IP Socket】基于线程池的TCP服务器 【Java TCP/IP 阅读详情

相关推荐

C Socket与Java Socket之间的通信

问题描述:拟在服务器上利用c或c++来编写服务器端程序,在android手机上编写客户端程序,实现通过手机客户端来访问服务器上的资源。由于在c中socket的使用方式跟Java中有一些不同,c中的使用方式比较麻烦,java中相对简单。本文中服务器端的环境是linux。若是windows,C Socket的使用方式会稍有不同。 Socket介绍 Socket(套接字)相当于一种特殊的IO。只不过

lp09160206的专栏 4080

C++跨平台开发——SOCKET网络编程中实现客户端对聊

一、案例 C++跨平台开发——关于解决SOCKET网络编程中客户端对聊的问题 二、实现分析 1、为什么服务器开启线程而不是进程? 线程的开销小,启动快,共享数据(不需要ipc就可以实现交互),所以一个线程一个客户端(效率提升将近10倍。 2、创建线程的时候传accepfd的原因 accepfd记录客户端,客户端每上线一个就覆盖一个accepfd,第一个accepfd就没了,利用值传参并保存下来。线程永远都停留在死循环内,保存下来的fd就不会被替换掉。(知道客户端下线) 3、自定义通信协议

hml111666的博客 4337

C++ socket 基本功能跨平台封装(好用)

真正可以使用的平台无关性的 C++ socket wrapper,没有做任何多余的事情,仅仅对 socket 的基本功能进行了平台无关性的封装,简洁原生。封装了:setoption, connect, close, send, recv, sendto, recvfrom, accept,bind 等基本方法。C++11 标准,macos/linux/windows 均进行了完全测试。

C++跨平台开发——关于解决SOCKET网络编程中客户端对聊的问题

前面我们在SOCKET网络编程学习中,简单实现了服务器为客户端单独开一个进程,客户端网络连接成功之后可以输入数据,并陆续给服务器发送消息,服务器则实现读取操作。 那么如果想要让客户端和客户端进行聊天该怎么办? ...

hml111666的博客 3125

跨平台socket封装

NULL 博文链接:https://chuqq.iteye.com/blog/1698875

跨平台socket demo

在网络上找了很久都没找到自己需要的资源,经过十数天的折腾终于弄出来了,分享给大家。 windows xp下使用apache.mina2框架搭建socket服务器,客户端在苹果系统下用c来实现的,因为用AsyncSocket框架无法正常与服务器交互,不知问题出在哪里,只好使用c了。 demo里包含windows下socket服务器、客户端工程以及mac os下客户端的工程,绝对超值!

跨平台tcp socket通信C++类(后续)

tcp socket在阻塞模式下,调用connect超时时间很长,所以尝试添加超时时间

Chocolate的博客 845

跨平台socket网络通信c语言实现

实现window与linux网络的传输时间测试,可以估计网络的速度,利用sendto、recvfrom、gettimeofdate实现。

基于VS2019 C++的跨平台(Linux)开发(2.2)——SOCKET网络编程

socket概述 为了简化开发通信程序的工作,由Berkely学校开发了一套网络通信程序的API函数标准 socket标准被扩展成window socket和unix socket linux中的网络编程通过socket接口实现。Socket既是一种特殊的IO,它也是一种文件描述符。一个完整的Socket 都有一个相关描述{协议,本地地址,本地端口,远程地址,远程端口};每一个Socket 有一个本地的唯一Socket 号,由操作系统分配。 ...

hml111666的博客 5512

跨平台的socket库,windows-linux-socket

跨平台的socket库,windows-linux-socket

Qwen3-Embedding选型指南:0.6B/4B/8B三版本性能对比与场景匹配建议

本文深入解析阿里开源的Qwen3-Embedding系列模型(0.6B/4B/8B)的性能差异与适用场景,提供从边缘计算到云端部署的实战选型建议。通过实测数据对比响应延迟、内存占用和多语言精度等核心指标,帮助技术团队根据业务需求选择最优模型版本,并分享边缘设备优化与云端成本测算策略。

qsc901234567的博客 892

Socket介绍及使用Java实现socket通信

使用Java实现socket通信。

weixin_49561506的博客 2万+

深入解析Mifare Classic Crypto1认证流程与密钥交换机制

本文深入解析Mifare Classic Crypto1认证流程与密钥交换机制,详细介绍了Crypto1加密算法的工作原理、认证初始化阶段、随机数交换与密钥流生成过程,以及双向验证步骤。文章还分析了Mifare Classic的安全漏洞,包括随机数生成缺陷和密钥流恢复攻击,并提供了Proxmark3实战演示和防护建议。

c6d7e8f9g的博客 898

JAVA—socket编程

socket编程,是在不同的进程间进行网络通讯的一种协议,在socket编程中基于TCP、UDP等协议做的一层封装,是一套系统所提供的的用于进行网络通信的编程接口。

皮皮治不痞痞 1万+

区块链技术在碳足迹数据存证与溯源中的应用深度解析

消费者扫描产品上的二维码,即可通过区块链浏览器查询到该产品的数字碳标签,并追溯其从茶园到货架的每一步碳足迹数据,以及这些数据是如何被智能合约自动计算和认证的,从而建立起强大的品牌信任。如果说哈希链解决了数据的“存”与“证”的问题,那么智能合约则解决了数据“用”与“管”的自动化问题。综上所述,虽然针对“碳足迹数据可追溯性”这一特定应用场景的公开、标准化的性能基准案例尚不丰富,但现有研究和企业级解决方案(特别是联盟链)已经证明,通过合理的技术选型和架构设计,区块链的性能可以满足实际商业需求。

百态·数智思维 | 聚焦大数据、量化与未来AI 1107

ubuntu20.04安装Qt5.15.2并配置环境

qt官方取消了离线安装的方式,所以推荐在线安装,当然,如果想要自己通过源码编译也可以,参考官方文档:https://wiki.qt.io/Building_Qt_5_from_Git。 在线安装: 1.到官方网站下载:wget https://download.qt.io/official_releases/online_installers/qt-unified-linux-x64-online.run 2.修改文件权限:chmod 777 qt-unified-linux-x64-online.run

f120854632的博客 8807

Java中的Socket你了解吗

Java中的普通Socket和NioSocket的简单介绍和使用。

个人博客,欢迎收藏。 2108

外骨骼机器人(五):步态分析之正常步态

研究病理步态之前,需要了解正常步态,作为判断标准。但是需要记住两个问题:1.“正常”因人而异,性别、年龄、身体情况都需要考虑在内,因此,需要对不同的个体选择合适的正常标准;2.即使病人的步态与正常步态有某种不同,这也不能说明这是不可取的,也不能说明应该把它变成“正常”步态。许多步态异常是对病人的一些问题的一种补偿,尽管异常,但它们仍然是有用的。步态周期的定义是连续为两次发生重复行走事件之间的时间间隔。尽管可以选择任何事件来定义步态周期,但通常使用一只脚接触地面的瞬间(“初始接触”)是方便的。

行者无疆的博客 1997

Java中的Socket编程详解

Socket(套接字)是网络通信的端点,允许在两台计算机之间通过网络进行数据交换。Socket是网络编程中必不可少的一部分,它建立在TCP/IP协议上,用于管理连接、传输数据。客户端Socket:用于连接远程服务器。服务器Socket:用于侦听客户端请求并与其建立连接。Java中的Socket编程通过和Socket类可以轻松实现客户端与服务器之间的通信。在实际开发中,Socket编程通常用于构建底层网络协议的基础。通过本文的示例,你应该对Java中的Socket编程有了基本的了解。

上进!努力!!! 7536

基于STM32L4XX、HAL库的ESP32-C3-WROOM-02-N4 WIFI模块驱动程序设计

支持802.11 b/g/n Wi-Fi (2.4GHz)RISC-V 32位单核处理器,主频高达160MHz。封装尺寸:18mm × 20mm × 3mm。工作温度范围:-40°C ~ 85°C。// 设置WiFi模式为STA。支持Bluetooth 5 (LE)// 发送AT指令测试通信。// 检查响应是否包含OK。内置4MB SPI Flash。// 连接TCP服务器。// 发送HTTP请求。// 初始化UART。// 建立TCP连接。低功耗设计,适合IoT应用。

zhusl6688的博客 385

大模型系列——一文看懂“提示词” vs “提示词工程” vs “上下文工程”

本文区分了AI领域的三个关键概念:提示词(Prompt)、提示词工程(Prompt Engineering)和上下文工程(Context Engineering)。提示词是直接输入给AI模型的指令文本;提示词工程则是系统化设计、测试和优化提示词的过程;而上下文工程是为AI构建动态上下文,提供恰当信息和工具的科学与艺术。文章通过翻译案例展示了提示词工程的迭代过程,并说明上下文工程在AI Agent中的核心作用——动态收集和组织必要信息。最后强调普通人只需掌握提示词编写,开发AI应用才需深入提示词工程,构建智能

2401_84052244的博客 750

java socket是什么_Java Socket

什么是SocketSocket的概念很简单,它是网络上运行的两个程序间双向通讯的一端,既可以接收请求,也可以发送请求,利用它可以较为方便地编写网络上数据的传递。所以简而言之,Socket就是进程通信的端点,Socket之间的连接过程可以分为几步:1、服务器监听服务器端Socket并不定位具体的客户端Socket,而是处于等待连接的状态,实时监控网络状态2、客户端请求客户端Socket发出连接请求,...

weixin_39916511的博客 601

【机器人技术基础】MATLAB Robotics Toolbox PUMA560 运动学正逆解

机器人技术基础实验2报告 1. 实验目的和要求 2. 实验手段 2.1 实验原理 2.2 函数详解 3. 实验主要内容 4. 实验结果和分析 4.1 正运动学求解 例1 例2 4.2 逆运动学求解 例1 例2 1. 实验目的和要求 掌握常见形式的机器人的D-H坐标系建立方法、运动学建模; 正逆运动学分析与求解; 使用Robotics Toolbox对直角坐标机器人、圆柱坐标机器人、球坐标机器人、PUMA560其中之一建立运动学模型,正逆求解和仿真。 2. 实验手段 2.1

【人工智障 | 计算鸡视觉 | 机器孩】 1万+

java手写Socket

在Java中使用Socket进行网络编程是非常基础且重要的技能。Socket编程允许我们通过网络连接不同的计算机,实现数据的发送和接收。本文将通过一个完整的Java Socket编程示例,来详细讲解如何创建服务器端和客户端程序,以及如何通过它们进行通信。代码和解释将从基础的Socket概念逐步展开,最终形成一个完整的网络通信程序。

Flying_Fish_roe的博客 1200

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

java socket 详解_JAVA SOCKET 详解

概述本人在开发学习NETTY的过程中,需要了解很多的网络开发知识,在此我总结一些关于socket的基础知识,大部分是网络总结,在此篇的随笔中记录socket的知识,以便于记录,如有问题欢迎大家斧正。SOCKET通信基本原理首先socket通常也叫做“套接字”,用于描述IP地址和端口,是一个通信连的句柄。应用程序通常通过“套接字”向网络发出请求或者应答网络请求。 socket通信是基于TCP/IP网...

weixin_39640372的博客 337

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

java之socket_Java之Socket

简述Java中Socket分为普通Socket和NioSocket两种,这里介绍Socket。我们可以把Socket比作两个城市间的交通工具,有了它可以在两城之间来回穿梭,交通工具有很多种,每种交通工具也有相应的交通规则。Socket也一样,也有多种。大多情况下使用的是TCP/IP的流套接字,它是一种稳定的通信协议。(TCP/IP与UDP的对比)Java中的网络通信是通过Socket实现的,Soc...

weixin_30143813的博客 170

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

上一篇: 【前端】Java Script
下一篇: 【Java】反射
CoderSharry
博客等级 码龄4年 515粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值