解决Java中socket使用getInputStream()阻塞问题

网友投稿 331 2022-11-15

解决Java中socket使用getInputStream()阻塞问题

目录socket使用getInputStream()阻塞用线程解决Socket的getInputStream阻塞1.背景2.问题3.原因4.解决办法5.Socket通信注意事项

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.getInputShttp://tream()方法会导致程序阻塞,直到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接口。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:采用USB控制器ISP1161实现USB主机功能的设计研究
下一篇:开源硬件Banana Pi BPI-R2的GPIO定义
相关文章

 发表评论

暂时没有评论,来抢沙发吧~