在Java中如何使用Socket进行通信_Java网络编程基础解析

发布时间 - 2026-01-07 00:00:00    点击率:
Java Socket通信核心是TCP流式连接封装,需手动处理协议解析、粘包等;客户端Socket连接服务端,服务端ServerSocket accept等待连接;读写阻塞且无超时,需显式close。

Java中Socket通信的核心逻辑是什么

Java的SocketServerSocket本质是TCP连接的封装,不处理协议解析、粘包、心跳或重连——这些都得自己补。客户端用Socket连服务端IP+端口,服务端用ServerSocket在指定端口accept()等待连接。一次连接对应一个双向字节流,读写操作阻塞,没超时机制,默认无限等。

如何写出可运行的最小Socket示例

以下是最简但能跑通的双端代码,注意关键点:

  • 服务端必须先启动,否则客户端new Socket("127.0.0.1", 8080)会抛ConnectException
  • 双方都需显式调用close(),否则端口可能被占用、连接不释放
  • BufferedReader.readLine()按行读取,要求发送方末尾带\n(如pw.println("hello")
import java.io.*;
import java.net.*;

// 服务端
public class SimpleServer {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(8080);
        Socket s = ss.accept(); // 阻塞直到有连接
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
        String line = br.readLine();
        pw.println("echo: " + line);
        s.close();
        ss.close();
    }
}
import java.io.*;
import java.net.*;

// 客户端
public class SimpleClient {
    public static void main(String[] args) throws IOException {
        Socket s = new Socket("127.0.0.1", 8080);
        PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        pw.println("test");
        System.out.println(br.readLine());
        s.close();
    }
}

为什么read()经常卡住或读不到完整数据

这是初学者最常踩的坑:TCP是流式协议,InputStream.read()只保证读至少1字节,不保证读完一整条消息。没有长度头、分隔符或固定包长时,根本无法判断“一条消息”在哪结束。

  • readLine()的前提是对方发的是文本且每行结尾有\n\r\n
  • read(byte[] b)时,返回值是实际读到的字节数,必须检查,不能直接当完整包处理
  • 不要依赖available()判断是否有数据——它只反映内核缓冲区当前字节数,不可靠
  • 真正健壮的做法是定义协议:比如前4字节为int表示长度,再读对应字节数

ServerSocket.accept()之后要不要开新线程

要。默认accept()是阻塞的,一个连接处理完才能接下一个;如果在accept()后的处理逻辑里做耗时操作(比如文件IO、数据库查询),后续连接会被排队卡住。

  • 简单场景可用new Thread(() -> handle(s)).start()
  • 高并发建议用ExecutorService管理线程池,避免无限制创建线程
  • 注意共享资源(如PrintWriter)不是线程安全的,每个连接应独占自己的输入输出流
  • JDK 1.7+ 可考虑try-with-resources自动关闭流,但需确保异常时仍能释放连接
真实项目里,几乎没人手写原始Socket——Netty、Spring Integration 或 HTTP 协议更常用。但理解底层阻塞模型、流边界、连接生命周期,是排查Connection resetBroken pipe、半关闭状态等问题的基础。


# java  # 字节  # 端口  # ai  # stream  # 网络编程  # .net  # connection reset  # 为什么  # red 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 在线制作视频的网站有哪些,电脑如何制作视频短片?  历史网站制作软件,华为如何找回被删除的网站?  Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】  JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)  如何快速搭建高效WAP手机网站吸引移动用户?  JavaScript如何实现路由_前端路由原理是什么  Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】  Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制  laravel怎么在请求结束后执行任务(Terminable Middleware)_laravel Terminable Middleware请求结束任务执行方法  如何在香港免费服务器上快速搭建网站?  如何挑选最适合建站的高性能VPS主机?  EditPlus中的正则表达式 实战(2)  如何在云指建站中生成FTP站点?  如何在万网开始建站?分步指南解析  如何用美橙互联一键搭建多站合一网站?  Laravel如何与Docker(Sail)协同开发?(环境搭建教程)  如何用VPS主机快速搭建个人网站?  高性能网站服务器部署指南:稳定运行与安全配置优化方案  详解vue.js组件化开发实践  Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】  香港服务器建站指南:外贸独立站搭建与跨境电商配置流程  Python并发异常传播_错误处理解析【教程】  如何在建站宝盒中设置产品搜索功能?  JavaScript如何实现类型判断_typeof和instanceof有什么区别  焦点电影公司作品,电影焦点结局是什么?  PHP正则匹配日期和时间(时间戳转换)的实例代码  Windows10如何更改计算机工作组_Win10系统属性修改Workgroup  在Oracle关闭情况下如何修改spfile的参数  如何在万网自助建站中设置域名及备案?  今日头条微视频如何找选题 今日头条微视频找选题技巧【指南】  瓜子二手车官方网站在线入口 瓜子二手车网页版官网通道入口  大连 网站制作,大连天途有线官网?  JS中对数组元素进行增删改移的方法总结  Laravel如何与Pusher实现实时通信?(WebSocket示例)  Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验  如何用虚拟主机快速搭建网站?详细步骤解析  如何在阿里云部署织梦网站?  专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?  韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐  Laravel如何生成PDF或Excel文件_Laravel文档导出工具与使用教程  javascript中闭包概念与用法深入理解  智能起名网站制作软件有哪些,制作logo的软件?  如何登录建站主机?访问步骤全解析  广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?  利用python获取某年中每个月的第一天和最后一天  如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?  Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权  VIVO手机上del键无效OnKeyListener不响应的原因及解决方法  北京网站制作的公司有哪些,北京白云观官方网站?  HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】