Socket编程 之 一种死锁现象

【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 阅读详情

刚接触socket编程的过程中,很容易出现死锁的现象。下面我来介绍一种死锁的原因和解决的方法。

先来看这段代码:

/*客户端发送一个信息到服务端*/
 Socket socket = new Socket("127.0.0.1", 8081);
 outputStream = socket.getOutputStream();
 outputStream.write("服务器我想要一个html文件".getBytes());

/*接受服务器传来的响应信息*/
 inputStreams = socket.getInputStream();
 byte[] bytes = new byte[1024];
 StringBuilder stringBuilder = new StringBuilder();
 int len = 0;
 while((len = inputStreams.read(bytes))!=-1){
     stringBuilder.append(new String(bytes,0,len));
 }

代码很简单。就是先往服务器发送一个信息,然后服务器解析完信息后,传回一个响应的内容。然后客户端再接受该响应。

再来看服务器端的代码:

 ServerSocket serverSocket = new ServerSocket(8081, 1, InetAddress.getByName("127.0.0.1"));
 /*接受客户端的socket,若没有连接,会一直阻塞到有连接进来*/
 Socket socket = serverSocket.accept();

 /*服务器解析客户端传来的信息*/
 inputStream = socket.getInputStream();
 StringBuilder sb = new StringBuilder();
 byte[] bytes = new byte[1024];
 int len = 0;
 while((len=inputStream.read(bytes))!=-1){
    sb.append(new String(bytes,0,len));
 }

 /*服务器解析完传来的信息后,做出响应*/
 outputStream = socket.getOutputStream();
 outputStream.write("html文件来了".getBytes());

1.假设服务器的线程先与客户端运行。ServerSocket被执行到,然后调用accept();处于阻塞,一直等到一个socket进来。

2.与此同时客户端生成了一个socket并且传来了一个信息“服务器我想要一个html文件”。writer被执行后会继续执行到inputStreams.read(),因为read是阻塞的会一直等到服务端把响应信息传回。所以出于阻塞中。

3.accept()接受到socket之后就会去解析客户端传来的信息了,执行到inputStream.read()的时候,也会被阻塞。有人问客户端不是传来了“服务器我想要一个html文件”的信息了吗?为什么read还会被阻塞啊。这是因为read还没有读到-1。

服务器没有读到-1,会以为还有信息要传来,于是也处于等到中。可是客户端已经传输好了,并且在等服务器给响应信息呢。于是就发生了死锁。

解决的办法有两种:

第一种方法close流,相当于给流中加入一个结束标记-1
第二种方法:s.shutdownOutput();//关闭客户端的输出流。

相当于给流中加入一个结束标记-1.这个样子服务器的输入流的reaLine方法就会读到一个-1,然后结束readLIne方法。也可以这样理解s.shutdownOutput();关闭的是客户端的输出流,同时服务器端的输入流也随之关闭。s.shutdownIntput();也是同样的道理,关闭客户端的输入流,同时服务器端的输出流也随之关闭。

通过socket.shutdownOutput()关闭输出流,但socket仍然是连接状态,连接并未关闭
如果直接关闭输入或者输出流,即:in.close()或者out.close(),会直接关闭socket

【Java TCP/IP Socket】TCP Socket通信中由read返回值造成的的死锁问题(含代码) 问题的引出     在第一章《基本套接字》中,作者给出了一个TCP Socket通信的例子——反馈服务器,即服务器端直接把从客户端接收到的数据原原本本地反馈回去,示例程序当然运行无误。      书上客户端代码如下: import java.net.Socket; import java.net.SocketException; import java.io.IOException; i 阅读详情

相关推荐

多线程与socket编程

tcp(语音聊天、视频聊天、线下缓存高强电影、qq远程控制、发邮件)死锁:A线程操作占用资源1没有释放,B线程再来操作资源1,造成死锁。发生在发送端:发送间隔短,数据短,由于优化机制就合并在一起发送了;发生在接收端:接收不及时,所以数据就在接收方的缓存端黏在一起了。粘包的本质:tcp协议的传输是流式传输,数据与数据之间没有边界。接收端先接受四字节,知道数据的长度,再按照长度接收数据。发送端先发送四字节数据长度,再按照长度发送数据。udp(在线播放视频、qq发消息、微信消息)2、tcp、udp特点。

摘 月 273

Socket引发的死锁问题。

刚刚看了下socket的知识,于是自己做了一个简单的从客户端向服务端传递图片的程序。 但是中间出现了一些小问题,程序曾经一度在某个位置进入等待状态,无法继续运行下去。      下面分别是服务端和客户端的代码....      客户端代码:     package cn.dzr.tcp.Client; import java.io.File; import java.io.Fi

fortheother的专栏 1909

Linux Socket编程实战指南

Linux Socket编程是一种允许应用程序之间通过网络进行通信的编程技术。理解它的基础知识对于开发网络应用程序至关重要。在本章中,我们将概述Socket编程的基本概念,为后续更深入的章节打下基础。Socket编程接口,也称为网络编程接口,是一种允许应用程序之间进行通信的编程方式。它是在1980年代由加州大学伯克利分校开发的,为Unix系统提供了跨网络通信的能力。如今,Socket已成为互联网通信中不可或缺的一部分,广泛应用于各类网络应用程序的设计与开发中。

weixin_36299472的博客 812

使用QT中QTcpSocket中的readall()函数出现接收不完全的解决办法

目录 一、问题 二、解决方案 1、发送端: 2、接收端 3、分析 一、问题 最近在QT中使用TCP协议发送数据过程出现了一点问题,在这里总结一下。当接受数据过大时,使用readll()函数读取缓冲区数据时,有时会出现数据接受不完全的信号,最开始我以为是数据丢包,后面多次实验后发现是readall()函数未将缓冲区数据读取完全,读取数据流获取数据的方法还是没有readall()函数使用方便,所以,我们就从发送数据的地方着手修改,建立一个数据报。 二、解决方案 1、...

kupePoem的专栏 7689

牛顿法vs高斯牛顿法vs LM算法:三行代码说清核心区别(附性能对比表格)

本文通过对比牛顿法、高斯牛顿法和LM算法的核心迭代代码,揭示了三者在非线性最小二乘优化中的本质区别。LM算法通过引入阻尼因子,在高斯牛顿法的快速收敛与梯度下降的稳定性之间取得平衡,成为工程实践中鲁棒性最强的首选。文章还提供了清晰的性能对比表格,帮助开发者根据初始估计和问题性质快速选择合适算法。

weixin_29062255的博客 419

Rockchip开发板FUSB302快充调试避坑指南:从设备树配置到驱动修改全流程

本文详细解析了在Rockchip开发板上调试FUSB302快充功能的全流程,重点涵盖设备树配置、驱动修改及硬件设计避坑指南。针对PD协议协商失败、电流倒灌等常见问题,提供了从软件配置到硬件排查的实战解决方案,帮助嵌入式工程师高效完成快充功能开发。

weixin_28256233的博客 114

ioctl socket buffer

ioctl在socket中的一些用法及示例 函数 : ioctl(int fd, int request, void * arg) 定义 :  功能 : 控制I/O设备, 提供了一种获得设备信息和向设备发送控制参数的手段. 参数 : int  fd      文件句柄. 用于socket时, 是socket套接字.        int  request 函数定义的所有操作. 关于socket的...

MyObject-C的专栏 1020

从Android到鸿蒙:UI框架迁移的实战指南与最佳实践

本文为Android开发者提供了将应用UI框架迁移至鸿蒙系统的实战指南。文章深入对比了Android命令式编程与鸿蒙ArkUI声明式编程的核心差异,详细讲解了从环境配置、布局迁移(如RecyclerView转List)、逻辑处理到多设备适配与性能优化的全流程最佳实践,帮助开发者高效完成迁移工作。

weixin_29208077的博客 433

Qt C++ TCP readyread不触发或者只触发几次,readAll()丢数据,收不全数据 waitForReadyRead

UDP是面向数据报的传输协议,发送的UDP报文都被接收端视为一条消息,若消息太长被分片,UDP协议也会完成组合后才呈现在内核缓冲区;即这种传输方式是有保护消息边界的。TCP是面向流的的传输协议,发送端可以一次发送不定长度的数据,而接收端也可以一次提取不定长度的数据。最近拉手别人的项目,发现 TCP 存在很多问题,如readyread不触发或者只触发几次,readAll()丢数据,收不全数据;QTcpSocket readyread不触发或者只触发几次,readAll()丢数据,收不全数据的原因及解决办法。

q610098308的专栏 4354

ADS8681数据手册没讲透的细节:SPI时序、量程切换与电压换算的避坑指南

本文深入解析ADS8681数据手册未提及的SPI时序优化、量程切换陷阱与电压校准技巧。针对树莓派5与ADS8681的SPI通信问题,提供CPOL/CPHA配置建议;详解量程切换的位操作玄机与寄存器配置流程;并提出三步校准法应对非理想供电环境,帮助开发者提升ADC测量精度。

weixin_29178069的博客 518

锐捷交换机配置SSH

锐捷交换机配置ssh 一、组网需求 通过ssh功能可以远程登录管理设备 二、配置步骤 全局开启ssh服务,并且指定ssh版本 Ruijie>enable Ruijie#configure terminal Ruijie(config)#enable service ssh-server ------>开启SSH服务,默认关闭 Ruijie(config)#ip ssh version 2 ------>默认1.99版本,设置为版本2 添加登

Loners_fan的博客 1万+

网络编程Socket死锁的理解和分析

现在我们知道为什么只有WebServer能收到“你好啊”,而Browser01不能收到“嗯嗯,你好啊”,因为使用InputStream+循环读取数据,WebServer在读完数据后,还会进行一次多余的读取,试图利用read()返回-1来退出循环,而事与愿违,SocketInputStream和普通的文件字节读取流不同,即使管道现在没有数据,SocketInputStream也不会返回-1,而是调用socketRead0,最后阻塞,直到对方写入才得到数据并返回;方案三:使用多线程,将读和写放到不同线程中去。

m0_65653648的博客 1060

手把手教你学simulink实例:基于Simulink的风力发电系统建模与仿真

风力发电作为一种清洁、可再生的能源形式,近年来得到了快速发展。风力发电系统的性能优化和控制策略设计对于提高发电效率、降低运行成本具有重要意义。本项目旨在使用MATLAB/Simulink平台,对风力发电系统进行建模与仿真,研究其动态特性,并验证控制策略的有效性。通过建立风力发电机、传动系统、发电机及电力电子变换器等子系统的模型,实现对风力发电系统的全面分析。

MHD0815的博客 558

Socket编程中的踩坑点

文章目录1 ObjectInputStream和ObjectOutputStream之间通信的死锁现象1.1 第一个解释1.2 第二个解释1.3 解决办法2 对象输出流无法写入的问题2.1 哪些写入流操作需要手动flush?2.1.1 字节流OutputStream2.1.2 字符流Writer2.1.3 总结2.2 延展:Java io中的flush操作 1 ObjectInputStream和ObjectOutputStream之间通信的死锁现象 1.1 第一个解释 Socket编程中一个很奇怪的现象

Darren的博客 1281

SQL注入详解

SQL注入(SQL Injection)是一种常见的Web安全漏洞,主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱库、被删除、甚至整个服务器权限陷)。 即:注入产生的原因是后台服务器接收相关参数未经过滤直接带入数据库查询...

渗透之路,攻防之间皆学问 26万+

Ultralytics 框架中 model.predict() 返回的 results 对象的详细解析

通过掌握 results 对象的使用方法,您可以快速实现模型部署、数据分析与可视化。

浩瀚之水的专栏 747

Java Socket「饥饿死锁」问题

Socket是指网络上端到端的通信机制,一般基于传输层协议。本文以Java为例,专门讨论TCP协议的Socket编程可能遇到的饥饿、死锁问题。UDP协议的Socket编程也可以参考。

Foxir的专栏 3109

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Java Socket中使用ObjectInputStream发生死锁

 Socket编程中一个很奇怪的现象:用DataInputStream对象没错,但改为ObjectInputStream就出错了,而且try...catch还抓不到异常。 例如在Socket客户端中,使用DataInputStream进行下述编程,很正常,不会出现问题:  DataInputStream dis = new DataInputStream(socket

wenhuadream的专栏 2136

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

多线程与Socket编程

一、死锁 定义: 指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。 由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象:死锁. 解决办法: ...

baiqing9561的博客 189

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

【Socket编程一】Java Socket编程入门介绍

Java Socket编程入门介绍 1 计算机之间通信条件 在介绍Socket之前先简单介绍下计算机之间通讯所需要的条件:IP地址,协议,端口号。 IP地址:为实现网络中不同计算机之间的通信,每台计算机都必须有一个唯一的标识---IP地址。     举个例子,在电话通讯中,电话用户是靠电话号码来识别的。同样,在网络中为了区别不同的计算机,也需要给计算机指定一个连网专用号码,这个号码就是“I

noaman_wgs的博客 1073

Java Socket中使用ObjectInputStream对象的注意事项

Socket编程中一个很奇怪的现象:用DataInputStream对象没错,但改为ObjectInputStream就出错了,而且try...catch还抓不到异常。…… Socket编程中一个很奇怪的现象:用DataInputStream对象没错,但改为ObjectInputStream就出错了,而且try...catch还抓不到异常。 例如在Socket客户端中,使用Data...

weixin_33816611的博客 894

【Java TCP/IP Socket编程】----深入剖析----TCP数据传输中的死锁和性能

目录   死锁问题 数据传输性能 案例 --------笔记来自于书籍《Java TCP/IP Socket编程》 死锁问题 在TCP数据传输底层实现中(详细参见https://blog.youkuaiyun.com/lili13897741554/article/details/83104539)可能会出现死锁的情况,因此程序协议必须设计得非常小心,避免死锁的发生。以下情况可能导致死锁: 1...

梦悠哉的博客 690

python网络编程:TCP通信中死锁程序的设计与实现

一、TCP编程流程 服务器根据地址类型(ipv4,ipv6)、socket类型、协议创建socket 服务器为socket绑定ip地址和端口号 服务器socket监听端口号请求,随时准备接收客户端发来的连接,这时候服务器的socket并没有被打开 客户端创建socket 客户端打开socket,根据服务器ip地址和端口号试图连接服务器socket 服务器socket接收到客户端socket请求,被动打开,开始接收客户端请求,直到客户端返回连接信息。这时候socket进入阻塞状态,所谓阻塞即accept()

qq_43775063的博客 909

第六篇:JAVA网络编程之TCP Socket通信中由read返回值造成的的死锁问题(含代码)

书上示例     在第一章《基本套接字》中,作者给出了一个TCP Socket通信的例子——反馈服务器,即服务器端直接把从客户端接收到的数据原原本本地反馈回去。      书上客户端代码如下: [java] view plain copy import java.net.Socket;   import java.net.SocketExc

u012426327的专栏 648
上一篇: Java NIO 之 Socket开篇
下一篇: Java 的 四种引用
CallMeJiaGu
博客等级 码龄12年 149粉丝 99原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值