当前位置:   article > 正文

Java 网络编程时序问题_java如何解决网络问题造成的请求顺序错乱的问题

java如何解决网络问题造成的请求顺序错乱的问题

起因

这两天在做有关网络的编程练习,发现网路已经联通,但是服务器端接收不到数据,排查了好久,功能一个个测试了之后,服务端的代码没有问题了.焦点落在客户端.最后通过查看源代码,发现原来是要按照严格的时序来进行操作.如下:
1. 创建URL实例;
2. 获取URLConnection 实例,如果单纯的只是从服务器读数据,直接从URL实例读就可以了;
3. setDoOutput 设置输出功能,这样就相当于POST 方式;
4. 打开链接服务器的一个连接,这一步其实可以省略;
5. getOutputStream()获取输出流,此方法会隐式打开与服务端的连接;
6. write()将数据写到输出流;
7. close()关闭输出流;
8. getOutputStream()获取输入流;
9. read()从输入流读取服务端返回数据;
10. close()关闭输入流.

这其中,第8步 必须 在第7步 之后,否则数据是无法传输到服务端的.因为在使用getOutputStream() 的同时,会将getOutputStream() 获取的输出流关闭,这就造成实际上并没有把数据写出去,因此服务器端自然无法接收到数据.

好了,TL;DR,如果这是为了知道原因,到这一步也就完了,下面的就没必要看了.

下面是源码分析:

URLConnection#openConnection()

位置:java/net/URL.java

public URLConnection openConnection() throws java.io.IOException {
    return handler.openConnection(this);
}

//其中 handler 为
URLStreamHandler handler = handlers.get(protocol);
//Handlers 为HashTable的实例
static Hashtable<String,URLStreamHandler> handlers = new Hashtable<>();
//那么, 既然是HashTable , 有get 就会有put ,我们看看put 在哪?通过寻找发现,handlers.put() 仅仅有一处:在static URLStreamHandler getURLStreamHandler(String protocol)中
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

static URLStreamHandler getURLStreamHandler(String protocol) {

        URLStreamHandler handler = handlers.get(protocol);
        if (handler == null) {

            boolean checkedWithFactory = false;

            // Use the factory (if any)
            if (factory != null) {
                handler = factory.createURLStreamHandler(protocol);
                checkedWithFactory = true;
            }

            // Try java protocol handler
            if (handler == null) {
                String packagePrefixList = null;

                packagePrefixList
                    = java.security.AccessController.doPrivileged(
                    new sun.security.action.GetPropertyAction(
                        protocolPathProp,""));
                if (packagePrefixList != "") {
                    packagePrefixList += "|";
                }

                // REMIND: decide whether to allow the "null" class prefix
                // or not.
                packagePrefixList += "sun.net.www.protocol";

                StringTokenizer packagePrefixIter =
                    new StringTokenizer(packagePrefixList, "|");

                while (handler == null &&
                       packagePrefixIter.hasMoreTokens()) {

                    String packagePrefix =
                      packagePrefixIter.nextToken().trim();
                      //通过反射获取实际的 URLConnection 的子类
                        String clsName = packagePrefix + "." + protocol +
                          ".Handler";
                        Class<?> cls = null;
                        try {
                            cls = Class.forName(clsName);
                        } catch (ClassNo
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/920517
推荐阅读
相关标签
  

闽ICP备14008679号