`
yznxing
  • 浏览: 367314 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java中socket通讯的小陷阱

    博客分类:
  • java
阅读更多

1:在java的服务端代码:

 

public class SimpleServerSocket {
    public static void main(String[] args) {
        try {
            ServerSocket server = new ServerSocket(6789);
            Socket client;
            while (true) {
                try {
                    client = server.accept();
                    System.out.println(client.getInetAddress());

                    System.out.println("server waiting for getInputStream " + System.currentTimeMillis());

                    ObjectInputStream input = new ObjectInputStream(client.getInputStream());

                    System.out.println("server waiting for getOutputStream() " + System.currentTimeMillis());

                    ObjectOutputStream output = new ObjectOutputStream(client.getOutputStream());

                    System.out.println("server waiting for reading client " + System.currentTimeMillis());

                   

                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

            //client.close();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}
 

 

2: 客户端的代码:

 

public class SimpleClientSocket {
    public static void main(String[] args) {
        Socket server;
        try {
            server = new Socket("127.0.0.1", 6789);

            /**
             * 下面这两行的顺序改变试试
             */
            ObjectInputStream input = new ObjectInputStream(server.getInputStream());
            ObjectOutputStream output = new ObjectOutputStream(server.getOutputStream());

            System.out.println(server.getInetAddress());

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}
 

 

可以试下再本机运行。如果client和server都是先进行getInputStream
那 么程序运行的时候就会一直堵塞。不能成功建立通讯。

但是如果将client调换下顺序,就可以成功 建立连接。

目前猜想的原因是在TCP三次握手的时候堵塞住了吧,具体原因还不是很清楚,继续研究 中!~


=========================================================================

目 前原因已经找到,主要问题是出在构造ObjectInputStream的时候出问题的 。看 下源码:
public ObjectInputStream(InputStream in) throws IOException {
verifySubclass();
bin = new BlockDataInputStream(in);
handles = new HandleTable(10);
vlist = new ValidationList();
enableOverride = false;
readStreamHeader();
bin.setBlockDataMode(true);
    }

读取stream的header的时候,源码:
short s0 = bin.readShort();
这个方法会阻塞的,直 到读到东西位置!!

因此,如果客户端跟服务端都先构造ObjectInputStream的话,就 会互相堵塞,而如果其中一方先构造
ObjectOutputStream的时候就不会出问题,这是因为构造 ObjectOutputStream的时候会有一个方法,看源码:

public ObjectOutputStream(OutputStream out) throws IOException {
verifySubclass();
bout = new BlockDataOutputStream(out);
handles = new HandleTable(10, (float) 3.00);
subs = new ReplaceTable(10, (float) 3.00);
enableOverride = false;
writeStreamHeader();
bout.setBlockDataMode(true);
        if (extendedDebugInfo) {

   debugInfoStack = new DebugTraceInfoStack();
} else {
   debugInfoStack = null;
        }   
    }

wirte的源码:
 protected void writeStreamHeader() throws IOException {
bout.writeShort(STREAM_MAGIC);
bout.writeShort(STREAM_VERSION);
    }

这 里会写一个魔数和一个版本号,这样构造ObjectInputStream的时候就会读取到东西啦。
至此问题得以弄清楚!~





1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics