解决Java中socket使用getInputStream()阻塞问题
socket使用getinputstream()阻塞
今天用socket进行编程练习时,发现程序到了getinputstream()这里就进行不下去了
socket socket = new socket("127.0.0.1", 800); objectinputstream reader = new objectinputstream(socket.getinputstream()); system.out.println("a"); objectoutputstream writer = new objectoutputstream(socket.getoutputstream());
就这样的一个测试代码,a不会打印出来
后来发现是getinputstream()会一直阻塞在那里阻塞
我把两行代码调了一下就好了,还不太清楚原因,先记下来
socket socket = new socket("127.0.0.1", 800); objectoutputstream writer = new objectoutputstream(socket.getoutputstream()); system.out.println("a"); objectinputstream reader = new objectinputstream(socket.getinputstream());
用线程解决socket的getinputstream阻塞
1.背景
在socket通信中,当我们希望传输对象时,往往会用到输入/输出对象流。
objectinputstream in=new objectinputstream(socket.getinputstream()); objectoutputstream out=new objectoutputstream(socket.getoutputstream());
2.问题
当程序调用socket.getinputstream()程序被被卡住。
3.原因
socket.getinputstream()方法会导致程序阻塞,直到inputstream收到对方发过来的报文消息,程序才会继续往下执行。
public objectinputstream(inputstream in) throws ioexception的官方api显示:
creates an objectinputstream that reads from the specified inputstream. a serialization stream header is read from the stream and verified. this constructor will block until the corresponding objectoutputstream has written and flushed the header. [1]
4.解决办法
用线程的方式处理输入流。以下为示例代码:
//===============客户端代码 socketclient.java=====================
import java.io.ioexception; import java.io.objectinputstream; import java.io.objectoutputstream; import java.net.socket; import java.net.unknownhostexception; public class socketclient { private socket socket; private objectoutputstream out; private objectinputstream in; public socketclient(){ try { socket=new socket("localhost",8081); out=new objectoutputstream(socket.getoutputstream()); readthread readthread=new readthread(); readthread.start(); } catch (unknownhostexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } } public void sendmessage(string msg){ system.out.println("send message:"+msg); try { out.writeobject(msg); out.flush(); } catch (ioexception e) { e.printstacktrace(); } } class readthread extends thread{ boolean runflag=true; public void run(){ try { in=new objectinputstream(socket.getinputstream()); } catch (ioexception e1) { e1.printstacktrace(); } while(runflag){ if(socket.isclosed()){ return; } try { object obj=in.readobject(); if(obj instanceof string){ system.out.println("client recive:"+obj); } } catch (ioexception e) { e.printstacktrace(); } catch (classnotfoundexception e) { e.printstacktrace(); } } } public void exit(){ runflag=false; } } public static void main(string[] args) { socketclient socketclient=new socketclient(); system.out.println("build socketclient"); try { thread.sleep(1000); } catch (interruptedexception e) { e.printstacktrace(); } socketclient.sendmessage("hello first."); try { thread.sleep(1000); } catch (interruptedexception e) { e.printstacktrace(); } socketclient.sendmessage("hello second."); } }
//============服务器端代码 socketservice.java===========
import java.io.ioexception; import java.io.objectinputstream; import java.io.objectoutputstream; import java.net.serversocket; import java.net.socket; import java.net.socketexception; import java.util.date; public class socketservice { serversocket serversocket; public socketservice(){ try { serversocket=new serversocket(8081); while(true){ socket socket=serversocket.accept(); socketservicethread sst=new socketservicethread(socket); sst.start(); } } catch (ioexception e) { e.printstacktrace(); } } class socketservicethread extends thread{ socket socket; objectinputstream in; objectoutputstream out; boolean runflag=true; public socketservicethread(socket socket){ if(null==socket){ runflag=false; return; } this.socket=socket; try { out=new objectoutputstream(socket.getoutputstream()); } catch (ioexception e) { e.printstacktrace(); } } public void run(){ if(null==socket){ system.out.println("socket is null"); return; } try { in=new objectinputstream(socket.getinputstream()); while(runflag){ if(socket.isclosed()){ system.out.println("socket is closed"); return; } try { string obj=(string)in.readobject(); if(obj instanceof string){ system.out.println("server recive:"+obj); date date=new date(); out.writeobject("["+date+"]"+obj); out.flush(); } else{ system.out.println("server recive:"+obj); } } catch (classnotfoundexception e) { e.printstacktrace(); } catch (socketexception e){ e.printstacktrace(); return; } catch (ioexception e){ e.printstacktrace(); } } } catch (ioexception e1) { e1.printstacktrace(); return; } catch (exception e){ return; } } public void exit(){ runflag=false; } } public static void main(string[] args) { system.out.println("===============start service==============="); new socketservice(); } }
5.socket通信注意事项
(1).writexxx()方法后一般用flush()来把缓存内容发送出去。
(2).发送对象时,对象必须串行化,即该对象需要实现serializable接口。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
上一篇: python 面向对象之class和封装
下一篇: Python项目打包成exe文件