技术库 > Java

解决Socket的getInputStream阻塞

技术库:tec.5lulu.com

1.背景

from:tec.5lulu.com

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接口。

解决Socket的getInputStream阻塞


标签: java socket public本文链接 http://tec.5lulu.com/detail/110dpn2ehwgc285f1.html

我来评分 :6.1
0

转载注明:转自5lulu技术库

本站遵循:署名-非商业性使用-禁止演绎 3.0 共享协议

www.5lulu.com