socket客户端断开连接连接服务端没报错,但服务端收不到客户端发的数据,客户端也收不到返回

网络编程中服务器发送的消息,客户端收不到也没有反应的几点原因
在使用 PrintWriter
时出现的问题
原因: 因为PrintWriter.print()比PrintWriter.println()少了换行符,客户端永远收不到一行结束的标志。
直到服务器退出时客户端才可以看见返回的消息
在使用 BufferedWriter
时也会出现同样的问题
当使用write()方法时为了避免上述问题可以这样使用:
还有一种可能是在关闭流的时候把socket也关闭了。
例如,当这个socket既有读又有写(socket.getInputStream() ,
socket.getOutputStream())的时候,
当读完了数据,以后也不再用了这个流了,根据流的使用原则,此时流应该关闭,但是在socket中,我尝试了很多次,
当关闭任何一个与socket有关的流时,再去判断socket,却发现此时socket已经关闭。程序会报异常。
有可能是我的程序有问题,但是根据以上思路,我尝试了另一种解决方法:
方法原理很简单,就是在流之间传递数据的时候,在最后面加上一个标志字符串,譬如“end”并且单独成行,
那么在读取流数据的时候,就可以判断是否读到最后了,如果读到最后,则使用 break退出循环,而流不再显示关闭。
这样就不会出现阻塞现象,程序可以很好的跑起来
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!netty 做socket服务端,客户端是其他方式实现的(客户端flush之后调用了shutdownOutput)。能收到请求,不能给客户端响应。
客户端是java.net.Socket 实现。
Socket socket = new Socket(ip, port);
&& &&& &&& &socket.setSoTimeout(30000);
&& &&& &&& &DataOutputStream out = new DataOutputStream(socket
&& &&& &&& &&& &&& &.getOutputStream());
&& &&& &&& &out.write(send.getBytes("GBK"));
&& &&& &&& &out.flush();
&& &&& &&& &socket.shutdownOutput();
去掉shutdownOutput(),请求应答都正常。加上之后,netty服务端写响应信息时,channnel状态isWritable,isActive 全部为false,不能正常写入响应。是什么原因呢?
我用mina做服务端的时候也碰到这样的问题了,客户端调用shutdownoutput方法后,服务端iosession获取不到客户端地址了,客户端收不到返回报文信息,也不报错,请问mina有什么配置参数或其它方法解决这一问题吗?
--- 共有 1 条评论 ---
看上楼,mina没仔细研究过,不过应该是类似的
问题已解决,netty服务端设置ChannelOption参数ALLOW_HALF_CLOSURE=true ,允许半关闭socket即可。默认为false,客户端shutdownoutput时,SocketChannel.read(..) 接收到 -1 时,会关闭整个channel。
为什么要shutdownOutput,其实你点进去看下源码就晓得了,多半output 或者 input 关闭都会导致关闭对应的 socket 的。
通道只有一个,状态分为几个。
客户端请求关闭通道,服务端就把通道已经关闭了?
--- 共有 1 条评论 ---
是啊,按理说关闭的只是写通道博客分类:
&&& 什么是socket
   所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
   以JDK-1.6为例,Socket和ServerSocket类库位于java.net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
   重要的Socket API:
   java.net.Socket继承于java.lang.Object,有八个构造器,其方法并不多,下面介绍使用最频繁的三个方法,其它方法大家可以见JDK-1.6文档。
   . Accept方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。"阻塞"是一个术语,它使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。
   . getInputStream方法获得网络连接输入,同时返回一个IutputStream对象实例,。
   . getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。
   注意:其中getInputStream和getOutputStream方法均会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。
客户端和服务器端通过socket发送消息和接收消息的过程:
接收消息的过程
发送消息的过程
package com.jysd.
import java.io.BufferedR
import java.io.IOE
import java.io.InputStreamR
import java.io.PrintW
import java.net.S
import java.net.UnknownHostE
public class Client {
public void go() throws UnknownHostException, IOException{
//向服务器端发送请求,服务器IP地址和服务器监听的端口号
Socket client = new Socket("127.0.0.1", 4242);
//通过printWriter 来向服务器发送消息
PrintWriter printWriter = new PrintWriter(client.getOutputStream());
System.out.println("连接已建立...");
//发送消息
printWriter.println("hello Server");
printWriter.flush();
//InputStreamReader是低层和高层串流之间的桥梁
//client.getInputStream()从Socket取得输入串流
InputStreamReader streamReader = new InputStreamReader(client.getInputStream());
//链接数据串流,建立BufferedReader来读取,将BufferReader链接到InputStreamReder
BufferedReader reader = new BufferedReader(streamReader);
String advice =reader.readLine();
System.out.println("接收到服务器的消息 :"+advice);
reader.close();
public static void main(String[] args) throws UnknownHostException, IOException {
Client c = new Client();
服务器端:
package com.jysd.
import java.io.BufferedR
import java.io.IOE
import java.io.InputStreamR
import java.io.PrintW
import java.net.ServerS
import java.net.S
public class Server {
private ServerS
private InputStreamReader inputStreamR
private BufferedReader bufferedR
public void server(){
//让服务器端程序开始监听来自4242端口的客户端请求
if (ss==null) {
ss = new ServerSocket(4242);
System.out.println("服务器启动...");
//服务器无穷的循环等待客户端的请求
while(true){
*accept()方法会在等待用户的socket连接时闲置着,当用户链接
*上来时,此方法会返回一个socket(在不同的端口上)以便与客户端
*通信。Socket与ServerSocket的端口不同,因此ServerSocket可以
*空闲出来等待其他客户端
//这个方法会停下来等待要求到达之后再继续
Socket s = ss.accept();
inputStreamReader = new InputStreamReader(s.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
String request = bufferedReader.readLine();
System.out.println("接收到了客户端的请求:"+request);
PrintWriter printWriter = new PrintWriter(s.getOutputStream());
String advice = "I am Server";
printWriter.println(advice);
printWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
public static void main(String[] args) {
Server server = new Server();
server.server();
浏览 35334
men4661273
浏览: 197701 次
来自: 北京
推荐一个socket编程的异步socket类库,https:/ ...
处理excel的时候,列太多,已经把pdf设置横向,依然不行, ...
小白马 写道能不能发一下源代码啊https://git.osc ...
不错不错,总结的挺好的。插件实现也是不错的,PageOffi ...
能不能发一下源代码啊
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'socket阻塞的解决办法,socket客户端收不到响应报文的处理
问题:java编写的socket服务端,C编写的客户端,通信的时候,C接收不到响应报文。
原因:服务端使用了readLine(),一直在等待客户端报文的结束符,造成阻塞。
处理办法:用缓存替换readLine(),具体代码如下:
public void run() {
PrintWriter pw =OutputStreamWriter os =InputStream is =try {System.out.println("socket请求处理中");SStringBuilder sb = new StringBuilder();
is = socket.getInputStream();
//**********开始读取报文
byte[] buffer = new byte[8];
int len = -1;len = is.read(buffer);String SocketLength = new String(buffer, 0, len, SdUtils.MSG_CHARACTOR); //获取报文长度描述
sb.append(SocketLength);for(int i=0; i&SocketLength.length();i++){if(SocketLength.charAt(i) == '0'){}SocketLength = SocketLength.substring(i);
//获取报文长度}buffer = new byte[Integer.valueOf(SocketLength)];
len = is.read(buffer);String SocketContent = new String(buffer, 0, len, SdUtils.MSG_CHARACTOR);// 获取报文头报文体报文尾sb.append(SocketContent);line = sb.toString();
//******************读取结束lg.info("Thread-" + this.getId() + "读取到客户端信息:" + line);socket.shutdownInput();// 关闭输入流resultStr = resp.getSrcMsg();// 返回字符串报文// TODO 4、获取输出流,响应客户端的请求os = new OutputStreamWriter(socket.getOutputStream(),SdUtils.MSG_CHARACTOR);pw = new PrintWriter(os);pw.write(resultStr);pw.flush();lg.info("Thread-" + this.getId() + "返回客户端报文:" + resultStr);socket.shutdownOutput();} catch (Exception e) {e.printStackTrace();lg.error(e.getMessage());} finally {try {pw.close();os.close();is.close();socket.close();} catch (IOException e) {e.printStackTrace();}}}
小结,使用readLine()一定要注意:
1.读入的数据要注意有/r或/n或/r/n
2.没有数据时会阻塞,在数据流异常或断开时才会返回null
3.使用socket之类的数据流时,要避免使用readLine(),以免为了等待一个换行/回车符而一直阻塞
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!java socket技术 客户端实现不发送请求给服务端但是一直接收服务端发来的数据_百度知道
java socket技术 客户端实现不发送请求给服务端但是一直接收服务端发来的数据
服务端使用的是C语言做的,与客户端连通后服务端一直主动推送数据给客户端,客户端使用Java技术实现一直接收数据,该怎么去做?
我有更好的答案
监听你系统通信所用的端口,有数据就获取显示就可以了。例如你的服务器ip是168.12.1.16,使用的是2000端口号,Socket socket=new Socket(&168.12.1.16&,2000);DataOutputStream in=new DataOutputStream(socket.getInputStream());
是采用定时去读取信息吗?不发送请求给服务端 服务端会主动把数据推送过来吗?
当然也算是定时读取的一种特殊形式,但是并不需要你自己去实现。他会监听指定的通信端口,当服务器端有数据发送过来是,就能触发相应的事件,自己就可以获取到信息。
java 可以用apache mina实现Socket客户端。C语言的Socket server网上应该也有很多源码。看你的描述,应该类似保持长连接推送计算。简单描述是:a 客户端请求服务器端,请求订阅某个推送主题,b 服务器端给此连接编号,并将该连接保持(使用定期发送心跳报文的方式),将编号与连接保存在内存中。c 当服务器需要推送消息给客户端时,轮询保持的连接列表,逐一发送消息给客户端。以下是相关介绍链接:一般做推送服务,对服务器的内存要求比较高,现在流行使用Erlang或Go语言写服务器端。
本回答被网友采纳
说点泼冷水的话题首先确认什么是客户端,什么是服务端。从用户的角度,可见的、可操作的即是客户端,也就是你这里说的java开发的部分。而不可见的部分就是服务端,也就是你说的C部分。而从网络开发的角度,发起请求的是客户端,而接收请求的是服务端。这与用户感受有很大区别。当从java请求C的时候,java是客户端,C 是服务端。而当C主动请求时,则C就变成了客户端,而java 变成了服务端。所以,从网络开发的角度,java想成为此次通信的服务端,必须长期维护一个端口可用,而C 要访问这个端口。而java为了能够长期维护一个端口,一般采用socket 方式(其他方式也基本上都是基于socket的),由于java已经封装的很好了,只要new Socket(IP,port) 就可以 获得,同时,由于原来C 是服务器,而如果没有多个服务器同时向java端发送请求的话,基本连线程处理都不需要做的。
java 你不要关闭socket就好了。
其他1条回答
为您推荐:
其他类似问题
socket的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。

我要回帖

更多关于 socket 服务端 客户端 的文章

 

随机推荐