亚洲色成人网站www永久,亚洲欧美人成视频一区在线,亚洲国产成人高清在线观看,亚洲精品久久久久久动漫,亚洲国产精品久久电影欧美

數(shù)據(jù)專欄

智能大數(shù)據(jù)搬運工,你想要的我們都有

科技資訊

科技學院

科技百科

科技書籍

網(wǎng)站大全

軟件大全

HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
本人菜鳥,需要在webkit下實現(xiàn)html5中websocket的功能。請大神給個指點。
webkit主要是在Linux下進行開發(fā)。
技術問答
2014-05-06 20:08:08
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
需求:現(xiàn)在想要用webkit載入網(wǎng)頁的指定部分。
目前看來用chrome的developer tools 來編輯(修改,刪除等)節(jié)點的效果就特別適合,由于第一次使用webkit,完全沒找到文檔和合適的demo,如何實現(xiàn)這樣的效果,請各位指點!
技術問答
2014-02-22 16:46:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
@Lunar_Lin 你好,想跟你請教個問題:我用vs2008編譯webkit出現(xiàn)如下問題如何解決?
\cygwin\home\WebKit\Source\JavaScriptCore\wtf/unicode/icu/UnicodeIcu.h(27) : fatal error C1083: 無法打開包括文件:“unicode/uchar.h”: No such file or directory
CollatorICU.cpp
d:\cygwin\home\WebKit\Source\JavaScriptCore\wtf/unicode/icu/UnicodeIcu.h(27) : fatal error C1083: 無法打開包括文件:“unicode/uchar.h”: No such file or directory
AtomicString.cpp
d:\cygwin\home\WebKit\Source\JavaScriptCore\wtf/unicode/icu/UnicodeIcu.h(27) : fatal error C1083: 無法打開包括文件:“unicode/uchar.h”: No such file or directory
StringBuilder.cpp
d:\cygwin\home\WebKit\Source\JavaScriptCore\wtf/unicode/icu/UnicodeIcu.h(27) : fatal error C1083: 無法打開包括文件:“unicode/uchar.h”: No such file or directory
StringImpl.cpp
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
請您指教!
技術問答
2014-02-11 09:53:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
將J2Cache或jgroups的測試程序部署到阿里云(windows系統(tǒng)兩臺,內(nèi)網(wǎng)IP能ping通)、浪潮云(三臺linux,內(nèi)網(wǎng)IP連著),微軟云虛擬機(三臺linux,內(nèi)網(wǎng)IP連著),發(fā)現(xiàn)都無法連通,具體表現(xiàn)在不同機器跑的同一程序不能加入到同一個 JChannel 中, viewAccepted不觸發(fā)。 同樣的程序在公司局域網(wǎng)、一所學校的內(nèi)網(wǎng)服務器都沒問題。
測試代碼很簡單 import java.io.BufferedReader; import java.io.InputStreamReader; import org.jgroups.JChannel; import org.jgroups.Message; import org.jgroups.ReceiverAdapter; import org.jgroups.View; public class SimpleChat extends ReceiverAdapter { JChannel channel; public void viewAccepted(View new_view) { System.out.println("** view: " + new_view); } public void receive(Message msg) { String line = "[" + msg.getSrc() + "]: " + msg.getObject(); System.out.println(line); } /** Method called from other app, injecting channel */ public void start(JChannel ch) throws Exception { channel = ch; channel.setReceiver(this); channel.connect("ChatCluster"); eventLoop(); channel.close(); } private void start(String props, String name) throws Exception { channel = new JChannel(props); if (name != null) { channel.name(name); } channel.setReceiver(this); channel.connect("ChatCluster"); eventLoop(); channel.close(); } private void eventLoop() { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); while (true) { try { System.out.print("> "); System.out.flush(); String line = in.readLine().toLowerCase(); if (line.startsWith("quit") || line.startsWith("exit")) { break; } Message msg = new Message(null, null, line); channel.send(msg); } catch (Exception e) { } } } public static void main(String[] args) throws Exception { String props = "udp.xml"; String name = null; for (int i = 0; i < args.length; i++) { if (args[i].equals("-props")) { props = args[++i]; continue; } if (args[i].equals("-name")) { name = args[++i]; continue; } help(); return; } new SimpleChat().start(props, name); } protected static void help() { System.out.println("SimpleChat [-props XML config] [-name name]"); } }

配置文件udp.xml:
使用的是組播UDP, 運行java也加上 -Djava.net.preferIPv4Stack=true 參數(shù)
請教各位,在這些云服務器上部署jgroups的分布式程序,能使用UDP組播方式嗎? 需要服務商做什么配置或購買的機器有什么要求,才能使用?
如果不能使用,應該如何修改配置文件,把這個SimpleChat連通?
@紅薯


技術問答
2015-09-26 10:17:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
軟件版本:
用法:
報錯信息:
技術問答
2020-01-19 11:20:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
最近使用J2cache, 然后然后多次出現(xiàn)用著用著爆出來莫名的錯誤,有時候重啟一下,有時候更新一下maven,不定的會出各種錯誤,好尷尬,上一次更新了一下maven,然后集成shiro序列化出問題,后面找到原因,可能是加載jar包中默認的序列化配置。。。

這次重啟了一下出現(xiàn)如下錯誤。。。
[http-nio-8080-exec-1] INFO org.springframework.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet' [http-nio-8080-exec-1] INFO org.springframework.web.servlet.DispatcherServlet - Completed initialization in 15 ms [http-nio-8080-exec-1] INFO org.apache.shiro.session.mgt.AbstractValidatingSessionManager - Enabling session validation scheduler... [http-nio-8080-exec-1] INFO net.oschina.j2cache.util.SerializationUtils - Using Serializer -> [fst:net.oschina.j2cache.util.FSTSerializer] [http-nio-8080-exec-1] INFO net.oschina.j2cache.CacheProviderHolder - Using L1 CacheProvider : net.oschina.j2cache.caffeine.CaffeineProvider [http-nio-8080-exec-1] INFO net.oschina.j2cache.redis.RedisCacheProvider - Redis client starts with mode(single),db(0),storage(generic),namespace(),time(21ms) [http-nio-8080-exec-1] INFO net.oschina.j2cache.CacheProviderHolder - Using L2 CacheProvider : net.oschina.j2cache.redis.RedisCacheProvider [http-nio-8080-exec-1] INFO net.oschina.j2cache.redis.RedisPubSubClusterPolicy - Connected to redis channel:j2cache, time 144 ms. [http-nio-8080-exec-1] INFO net.oschina.j2cache.J2CacheBuilder - Using cluster policy : net.oschina.j2cache.redis.RedisPubSubClusterPolicy ìn
目前還沒確認什么影響的,記錄一下問題?。?!有遇到的或者知道的可以解答一下。。。
技術問答
2019-12-03 23:09:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
大神們,報這個異常是啥意思?
java.io.IOException: java.lang.RuntimeException: unknown object tag -65 at de.ruedigermoeller.serialization.FSTObjectInput.readObject(FSTObjectInput.java:205)at net.oschina.j2cache.util.FSTSerializer.deserialize(FSTSerializer.java:49) at net.oschina.j2cache.util.SerializationUtils.deserialize(SerializationUtils.java:66) at net.oschina.j2cache.Command.parse(Command.java:92) at net.oschina.j2cache.RedisCacheChannel.onMessage(RedisCacheChannel.java:283) at redis.clients.jedis.JedisPubSub.process(JedisPubSub.java:129) at redis.clients.jedis.JedisPubSub.proceed(JedisPubSub.java:102) at redis.clients.jedis.Jedis.subscribe(Jedis.java:2628) at net.oschina.j2cache.RedisCacheChannel$1.run(RedisCacheChannel.java:58) at java.lang.Thread.run(Thread.java:724) Caused by: java.lang.RuntimeException: unknown object tag -65 at de.ruedigermoeller.serialization.FSTObjectInput.instantiateSpecialTag(FSTObjectInput.java:334) at de.ruedigermoeller.serialization.FSTObjectInput.readObjectWithHeader(FSTObjectInput.java:294) at de.ruedigermoeller.serialization.FSTObjectInput.readObjectInternal(FSTObjectInput.java:270) at de.ruedigermoeller.serialization.FSTObjectInput.readObject(FSTObjectInput.java:247) at de.ruedigermoeller.serialization.FSTObjectInput.readObject(FSTObjectInput.java:202)
... 9 more
求指教,本人菜鳥
技術問答
2016-05-26 10:01:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
cache.getL1Provider().removeCache("test-1"); cache.getL2Provider().removeCache("test-1");
為什么還能從L2中取到緩存區(qū)test-1啊
技術問答
2019-06-05 09:53:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>> @紅薯 ,今天通過J2Cache做了個簡單的向后臺去數(shù)據(jù),測試時開了一個Chrome瀏覽器以及一個Firfox瀏覽器,剛開始redis控制臺正常顯示1個客戶端連接數(shù),但過數(shù)分鐘后,連接數(shù)突增到1000,打開chrome ,FF的debug工具也沒發(fā)生自動相后臺發(fā)送請求
技術問答
2015-01-15 15:27:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
今天跟 fastjson 作者 @wenshao 聊了會才找到 fastjson 如何實現(xiàn)類型無關的對象序列化
代碼如下: package net.oschina.j2cache.util; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.serializer.SerializerFeature; /** * 使用 fastjson 進行對象的 JSON 格式序列化 */ public class FastjsonSerializer implements Serializer { @Override public String name() { return "fastjson"; } @Override public byte[] serialize(Object obj) { return JSON.toJSONString(obj, SerializerFeature.WriteClassName).getBytes(); } @Override public Object deserialize(byte[] bytes) { return JSON.parse(new String(bytes), Feature.SupportAutoType); } }
J2Cache 已經(jīng)新增了這個特性,詳情請看 這里 。
J2Cache 使用 JSON 進行緩存數(shù)據(jù)序列化的方式目前有兩種,一種是 fst 自帶的 JSON 序列化,另外一種就是今天新增的 fastjson 的方式。
實際測試發(fā)現(xiàn) fst 的兼容性非常好,fastjson 在處理一些內(nèi)嵌的類型時候會報異常:
com.alibaba.fastjson.JSONException: default constructor not found. class net.oschina.j2cache.JSONSerializerTest$1
異常對應的代碼是: person.setJobs(new HashMap(){{ put("creawor", 3); put("moabc", 5); put("huateng", 3); put("oschina", 8); }});
J2Cache 提供的幾種數(shù)據(jù)序列化方案請看
https://gitee.com/ld/J2Cache/tree/master/core/src/net/oschina/j2cache/util
技術問答
2018-08-08 12:01:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
使用j2cache時,緩存數(shù)據(jù)報如下錯誤,怎么解決?
java.lang.RuntimeException: cannot support legacy JDK serialization methods in crossplatform mode. Define a serializer for this class java.sql.Timestamp
at org.nustaq.serialization.FSTClazzInfo.(FSTClazzInfo.java:176) ~[fst-2.57.jar:na]
at org.nustaq.serialization.FSTClazzInfoRegistry.getCLInfo(FSTClazzInfoRegistry.java:129) ~[fst-2.57.jar:na]
at org.nustaq.serialization.FSTObjectOutput.getFstClazzInfo(FSTObjectOutput.java:534) ~[fst-2.57.jar:na]
at org.nustaq.serialization.FSTObjectOutput.writeObjectWithContext(FSTObjectOutput.java:416) ~[fst-2.57.jar:na]
at org.nustaq.serialization.FSTObjectOutput.writeObjectInternal(FSTObjectOutput.java:327) ~[fst-2.57.jar:na]
at org.nustaq.serialization.serializers.FSTMapSerializer.writeObject(FSTMapSerializer.java:49) ~[fst-2.57.jar:na]
at org.nustaq.serialization.FSTObjectOutput.writeObjectWithContext(FSTObjectOutput.java:476) ~[fst-2.57.jar:na]
at org.nustaq.serialization.FSTObjectOutput.writeObjectInternal(FSTObjectOutput.java:327) ~[fst-2.57.jar:na]
at org.nustaq.serialization.serializers.FSTCollectionSerializer.writeObject(FSTCollectionSerializer.java:54) ~[fst-2.57.jar:na]
at org.nustaq.serialization.FSTObjectOutput.writeObjectWithContext(FSTObjectOutput.java:476) ~[fst-2.57.jar:na]
at org.nustaq.serialization.FSTObjectOutput.writeObjectWithContext(FSTObjectOutput.java:369) ~[fst-2.57.jar:na]
at org.nustaq.serialization.FSTObjectOutput.writeObjectFields(FSTObjectOutput.java:664) ~[fst-2.57.jar:na]
at org.nustaq.serialization.FSTObjectOutput.defaultWriteObject(FSTObjectOutput.java:546) ~[fst-2.57.jar:na]
at org.nustaq.serialization.FSTObjectOutput.writeObjectWithContext(FSTObjectOutput.java:458) ~[fst-2.57.jar:na]
at org.nustaq.serialization.FSTObjectOutput.writeObjectInternal(FSTObjectOutput.java:327) ~[fst-2.57.jar:na]
at org.nustaq.serialization.FSTObjectOutput.writeObject(FSTObjectOutput.java:285) ~[fst-2.57.jar:na]
at org.nustaq.serialization.FSTObjectOutput.writeObject(FSTObjectOutput.java:204) ~[fst-2.57.jar:na]
at org.nustaq.serialization.FSTConfiguration.asByteArray(FSTConfiguration.java:1182) ~[fst-2.57.jar:na]
at net.oschina.j2cache.util.FstJSONSerializer.serialize(FstJSONSerializer.java:57) ~[j2cache-core-2.5.1-release.jar:na]
at net.oschina.j2cache.util.SerializationUtils.serialize(SerializationUtils.java:78) ~[j2cache-core-2.5.1-release.jar:na]
at net.oschina.j2cache.Level2Cache.put(Level2Cache.java:172) ~[j2cache-core-2.5.1-release.jar:na]
at net.oschina.j2cache.CacheChannel.set(CacheChannel.java:290) ~[j2cache-core-2.5.1-release.jar:na]
at net.oschina.j2cache.CacheChannel.set(CacheChannel.java:265) ~[j2cache-core-2.5.1-release.jar:na]
技術問答
2018-08-28 16:43:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
@紅薯 薯哥您好,想跟你請教個問題:
看了你寫的J2Cache,不得不佩服。我之前只用過redis的key--value形式來保存數(shù)據(jù),J2Cache中有個region區(qū)域的概念不是很理解,麻煩您給點評下,我的理解是:比如說系統(tǒng)中有個用戶信息的模塊,我可以定義一個Sys_User的區(qū)域,然后正常的存入key 與 value。
疑問一:region的出現(xiàn)是不是只是為了刪除緩存時,刪除的更精確一點?
看了您的”前兩天網(wǎng)站訪問慢的問題定位過程以及最終解決辦法“博文,里面說”老系統(tǒng)使用 J2Cache 的 hash 模式在 Redis 存儲數(shù)據(jù),而新系統(tǒng)使用 J2Cache 的 generic 模式記錄數(shù)據(jù)。也就是說老系統(tǒng)操作 Redis 使用 hget/hset 這些方法,Region 對應的是 Redis 的一個 key,而具體的緩存數(shù)據(jù)是 key 對應的子 key 。而新系統(tǒng)直接是 get/set 這樣的方法,也就是說不同 Region 的所有 Key 都揉在一起形成一個巨大的哈希表“
疑問二:Region對應的是Redis的Key?這邊不太會懂,如果Region是Key的話,那原先的key要怎么存儲呢?
希望您能在百忙之中解惑,謝謝!

技術問答
2018-12-29 16:36:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
@紅薯 是不是j2cache不支持集群模式的reids,我的redis是集群部署的,然后我看j2cache客戶端好像用的是jedisclient,報異常redis.clients.jedis.exceptions.JedisMovedDataException : MOVED 15530 192.168.201.64:7002
技術問答
2018-07-10 19:08:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>> public static List getUserSubscribe(String dsname, Map paraMap, boolean cacheable, String clearCachePWD) { //獲取用戶訂閱的服務。數(shù)據(jù)庫中用戶訂閱的服務是有數(shù)據(jù)的,所以不應該打印111的。 List userSubscribeList = DbUtil.filterFind(dsname, 110, 0, 30, cacheable, paraMap, clearCachePWD); if(userSubscribeList.isEmpty()){//用戶訂閱為空,返回默認服務 System.out.println("111"); //獲取默認服務默 return DbUtil.filterFind(dsname, 111, 0, 11, cacheable, paraMap, clearCachePWD); } else {//用戶訂閱不為空時,合并系統(tǒng)強制推薦的服務。 System.out.println("222"); // //獲取系統(tǒng)強制推薦的服務 List sysTjList = DbUtil.filterFind(dsname, 158, 0, 8, cacheable, paraMap, clearCachePWD); //找出相同的服務 List sameList = new ArrayList(); //這里省略找出相同服務代碼 //去重 userSubscribeList.removeAll(sameList); //合并方法1:直接把去重后的用戶訂閱合并到系統(tǒng)強制推薦的服務里。 //使用這個方法合并。就會有問題:運行前兩次是正常的,都不會打印111。但第三次就會打印111了。 sysTjList.addAll(userSubscribeList); return sysTjList; //合并方法2:沒有問題 // List allList = new ArrayList(); // allList.addAll(sysTjList); // allList.addAll(userSubscribeList); // return allList; }
以上代碼邏輯簡單說明:
就是把從緩存里取出來的兩個list對像,使用addAll合并時,調(diào)用兩次后,第三次結果就變空集合了。
使用第二種方法合并就不會有問題。
實在找不出問題存在,有人知道的不。。
只使用的是j2cache當緩存。
技術問答
2018-08-24 11:18:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
1.j2cache是不是只能以hash方式存儲呢?
2.我使用cacheChannel.set(),在redis客戶端看value的時候 亂碼"ühello j2cache2" 如何解決呢?
技術問答
2018-07-10 16:13:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>> 為什么html表單不使用js加密后在提交???
技術問答
2017-01-11 15:43:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>> 開源中國app是用了哪個h5框架? 大家覺得哪個好,我在做一個內(nèi)容型的app的技術選型。
技術問答
2017-01-10 12:25:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
php如何把一個html文件轉(zhuǎn)為圖片
我的網(wǎng)站是這樣的,用戶寫了一個文章(比如)
那么,我想把這個文章生成一個靜態(tài)頁面。然后生成一張圖片出來

后面那一步生成一張圖片,是怎么樣做的
技術問答
2013-12-13 11:41:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
這個問題感覺有點打擦邊球。
現(xiàn)在想做一個在線音樂的部分。然而因為眾所周知的原因,很多API現(xiàn)在都不能用了:網(wǎng)易原來的API已經(jīng)全都不能用了,新的eapi的param參數(shù)簡直bug,雖然有明顯的規(guī)律但是就是不知道是咋加密的;酷狗的API看似簡單,然而歌曲地址的拼接完全摸不著頭緒;蝦米雖好,然而并不知道淘寶的開放平臺應該如何注冊,據(jù)說還需要以公司的形式申請才可以;QQ音樂?這是啥,能吃么……
不過感覺奇怪的是,像深度音樂的資源又是怎么獲取到的?也沒有看到深度有搭自己音樂庫的新聞或者類似的消息,那么他們是怎么獲取這些信息的(如果有請原諒咱的信息太閉塞了)?現(xiàn)在正在讀源代碼,不知道會不會有收獲啥的。
還請OSC的大神們給點提示,還有沒有類似的API可以使用的?(不打擦邊球的最好)
技術問答
2016-11-30 11:09:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>> 問一下本地的一個html界面,如何通過手機訪問,需不需要掛到外網(wǎng)什么的,能不能來個大神講的詳細點!
技術問答
2016-11-28 10:04:04
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>> 如上,input checkbox已經(jīng)選中,但是審查元素時沒有checked屬性。用change能監(jiān)聽到有checked屬性。這是什么鬼?
技術問答
2016-09-09 11:27:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
直接看代碼吧
  • xxx



我要的效果是點擊li能選中這個checkbox! 我這樣寫label,程序提示不能這么寫,但是運行出來得到了最終效果。 請問這樣寫會有什么問題嗎?如果不這么寫要怎么樣才能得到我要的效果?
技術問答
2016-09-08 13:55:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>> 插入什么樣的Html標簽可以不改變原文樣式?目前已知的有['',''],很急,求大神解答。
技術問答
2016-08-24 17:12:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>> 各位小伙伴好,請教個問題,如圖所示,怎么導航欄在內(nèi)容部分打開對應的內(nèi)容
技術問答
2016-08-22 17:58:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>> 初學前端,搜了全網(wǎng)沒找到好的框架資源(主要是想支持響應式),希望有經(jīng)驗的能給點意見。
技術問答
2016-08-22 16:44:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
wireshark3.2.23抓取tcp數(shù)據(jù)之后,用 “追蹤流” 的“tcp流”查看,發(fā)現(xiàn)用軟件模擬發(fā)送數(shù)據(jù)。
如果模擬發(fā)送的不斷開,查看時就會被合成一個內(nèi)容(上圖就是不斷開端口發(fā)了n次),除非模擬發(fā)送的斷開之后在發(fā)送,這個能設置嗎?


還有假設我時間點1,時間點2,時間點3個發(fā)了數(shù)據(jù),點時間點1 查看的信息會包含所有的
技術問答
2020-04-13 09:59:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
發(fā)現(xiàn)辦公室網(wǎng)絡訪問網(wǎng)站有點慢, 切換成4G就快了, 通過Wireshark抓包 發(fā)現(xiàn)很多如下的異常
Previous segment not captured
This frame is a out-of-order segment
Connection reset
能否表示 公司的網(wǎng)絡不正常呢 需要聯(lián)系運營商呢?
技術問答
2020-03-21 11:57:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
辦公網(wǎng)絡時不時訪問線上域名的接口很慢 時間都是花在建立連接上了 如下所示 建立連接就用了一分多鐘
也抓了包 但是看不出什么來 不知道是什么原因?qū)е?怎么解決


技術問答
2019-09-23 20:29:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>

電腦A通過自身無線網(wǎng)卡把網(wǎng)絡用wifi熱點的方式分享出去 電腦B C D通過電腦A這個熱點wifi鏈接上網(wǎng) 電腦A能通過Wireshark+Fiddler(或者 Wireshark+其他工具 )抓取到電腦B C D訪問的https明文內(nèi)容嗎?現(xiàn)在抓包測試是TLS密文的,不知道可行嗎?
感謝!


技術問答
2014-12-20 21:12:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
1、引言
在文章《 理論聯(lián)系實際:Wireshark抓包分析TCP 3次握手、4次揮手過程 》中,我們學會了用wireshark來分析TCP的“三次握手,四次揮手”,非常好用。這就是傳說中的錘子,拿著 錘子,看什么都像 釘子!在這本文中,我對將準 HTTP這顆釘子,狠狠地砸下去。。。
為了對網(wǎng)絡數(shù)據(jù)包的“流轉(zhuǎn)”有更加深刻的理解,我在docker(遠程)上部署一個服務,支持http方式調(diào)用。從客戶端(本地)用http方式請求其中的一個接口,并得到響應數(shù)據(jù)。同時本地通過wireshark抓包,遠程用tcpdump抓包,然后分析過程中的所有通信細節(jié)(悲劇是把美好的東西撕碎給人看,而我則是把復雜的東西撕碎了給人看)。
本文的主要內(nèi)容是: 先通過工具獲取HTTP通信的數(shù)據(jù)包,再來抽絲剝繭,深入傳輸層二進制的天地里,解密HTTP所有的通信細節(jié)。分析過程中,由點到面,將相關知識串接起來。市面上講HTTP協(xié)議的文章很多,但深入到傳輸層從2進制的角度來解析,則相當少見。 保證全篇讀完之后,你對HTTP的理解會上升一個臺階!
本文稍長,請在看本文時保持耐心。
(本文同步發(fā)布于: http://www.52im.net/thread-2456-1-1.html )
2、關于作者
饒全成: 畢業(yè)于華中科技大學,中科院計算所碩士,滴滴出行后端研發(fā)工程師。微信公眾號: 碼農(nóng)桃花源,個人博客: https://www.cnblogs.com/qcrao-2018/ 。
3、系列文章 1)本文是系列文章中的第8篇,本系列文章的大綱如下:
《 不為人知的網(wǎng)絡編程(一):淺析TCP協(xié)議中的疑難雜癥(上篇) 》
《 不為人知的網(wǎng)絡編程(二):淺析TCP協(xié)議中的疑難雜癥(下篇) 》
《 不為人知的網(wǎng)絡編程(三):關閉TCP連接時為什么會TIME_WAIT、CLOSE_WAIT 》
《 不為人知的網(wǎng)絡編程(四):深入研究分析TCP的異常關閉 》
《 不為人知的網(wǎng)絡編程(五):UDP的連接性和負載均衡 》
《 不為人知的網(wǎng)絡編程(六):深入地理解UDP協(xié)議并用好它 》
《 不為人知的網(wǎng)絡編程(七):如何讓不可靠的UDP變的可靠? 》
《 不為人知的網(wǎng)絡編程(八):從數(shù)據(jù)傳輸層深度解密HTTP 》(本文)
2)如果您覺得本系列文章過于專業(yè),您可先閱讀《網(wǎng)絡編程懶人入門》系列文章,該系列目錄如下:
《 網(wǎng)絡編程懶人入門(一):快速理解網(wǎng)絡通信協(xié)議(上篇) 》
《 網(wǎng)絡編程懶人入門(二):快速理解網(wǎng)絡通信協(xié)議(下篇) 》
《 網(wǎng)絡編程懶人入門(三):快速理解TCP協(xié)議一篇就夠 》
《 網(wǎng)絡編程懶人入門(四):快速理解TCP和UDP的差異 》
《 網(wǎng)絡編程懶人入門(五):快速理解為什么說UDP有時比TCP更有優(yōu)勢 》
3)《腦殘式網(wǎng)絡編程入門》也適合入門學習,本系列大綱如下:
《 腦殘式網(wǎng)絡編程入門(一):跟著動畫來學TCP三次握手和四次揮手 》
《 腦殘式網(wǎng)絡編程入門(二):我們在讀寫Socket時,究竟在讀寫什么? 》
《 腦殘式網(wǎng)絡編程入門(三):HTTP協(xié)議必知必會的一些知識 》
《 腦殘式網(wǎng)絡編程入門(四):快速理解HTTP/2的服務器推送(Server Push) 》
4)其它跟HTTP有關的文章:
《 從HTTP/0.9到HTTP/2:一文讀懂HTTP協(xié)議的歷史演變和設計思路 》
《 美圖App的移動端DNS優(yōu)化實踐:HTTPS請求耗時減小近半 》
《 一分鐘理解 HTTPS 到底解決了什么問題 》
《 一篇讀懂HTTPS:加密原理、安全邏輯、數(shù)字證書等 》
《 小白必讀:閑話HTTP短連接中的Session和Token 》
《 IM開發(fā)基礎知識補課:正確理解前置HTTP SSO單點登陸接口的原理 》
《 從HTTP到MQTT:一個基于位置服務的APP數(shù)據(jù)通信實踐概述 》
《 基于APNs最新HTTP/2接口實現(xiàn)iOS的高性能消息推送(服務端篇) 》
《 Comet技術詳解:基于HTTP長連接的Web端實時通信技術 》
《 WebSocket詳解(四):刨根問底HTTP與WebSocket的關系(上篇) 》
《 WebSocket詳解(五):刨根問底HTTP與WebSocket的關系(下篇) 》
4、在傳輸層捕獲HTTP報文
4.1 背景介紹
我手頭現(xiàn)在有一個地理幾何相關的服務,它提供一組接口對外使用。其中有一個接口是Fence2Area. 使用方傳入一個圍欄(由點的列表組成,點由<經(jīng)度,緯度>表示)、點的坐標系類型(谷歌地圖用的是wgs84, 國內(nèi)騰訊、高德用的是soso, 而百度用的是另一套自己的坐標系),接口輸出的則是圍欄的面積。
我請求服務的“Fence2Area”接口,輸入圍欄(fence)頂點(lng, lat)坐標、坐標系類型(coordtype),輸出的則是多邊形的面積(area).
一次正常的請求示例url, 這個大家都不陌生(我用docker_ip代替真實的ip): http://docker_ip:7080/data?cmd=Fence2Area&meta={"caller":"test","TraceId":"test"}&request={"fence":[{"lng":10.2,"lat":10.2}, {"lng":10.2,"lat":8.2}, {"lng":8.2,"lat":8.2}, {"lng":8.2,"lat":10.2}],"coordtype":2}
請求發(fā)出后,服務器進行處理,之后,客戶端收到返回的數(shù)據(jù)如下: {
"data": {
"area": 48764135597.842606
},
"errstr": ""
}
area字段表示面積,errstr表示出錯信息,空說明沒有出錯。
4.2 抓包
在真正發(fā)送請求之前,需要進行抓包前的設置。在本地mac,我用wireshark; 而在遠程docker上,我用tcpdump工具。
mac本地: 設置wireshark包過濾器,監(jiān)控本地主機和遠程docker之間的通信。 ip.addr eq docker_ip
點擊開始捕獲。
遠程docker: 該服務通過7080端口對外提供,使用如下命令捕獲網(wǎng)絡包: tcpdump -w /tmp/testHttp.cap port 7080 -s0
4.3 請求、捕獲、分析
準備工作做完,我選了一個神圣的時刻,在本地通過瀏覽器訪問如下url: http://docker_ip:7080/data?cmd=Fence2Area&meta={"caller":"test","TraceId":"test"}&request={"fence":[{"lng":10.2,"lat":10.2}, {"lng":10.2,"lat":8.2}, {"lng":8.2,"lat":8.2}, {"lng":8.2,"lat":10.2}],"coordtype":2}
這樣本地的wireshark和遠程的tcpdump都能抓取到HTTP網(wǎng)絡數(shù)據(jù)包。
【關閉服務進程】:
正式請求之前,我們先看一下幾種特殊的情形。
首先,關閉gcs服務進程,請求直接返回RST報文。
如上圖,我在請求的時候,訪問服務端的另一個端口5010, 這個端口沒有服務監(jiān)聽,和關閉gcs服務進程是同樣的效果??梢钥吹?客戶端發(fā)送SYN報文,但直接被遠程docker RST掉了。因為服務端操作系統(tǒng)找不到監(jiān)聽此端口的進程。
【關閉docker】:
關閉docker, 由于發(fā)送的SYN報文段得不到響應,因此會進行重試,mac下重試的次數(shù)為10次。
先每隔1秒重試了5次,再用“指數(shù)退避”的時間間隔重試,2s, 4s, 8s, 16s, 32s. 最后結束。
【重啟docker】:
先進行一次正常的訪問,隨后重啟docker。并再次在本地訪問以上url, 瀏覽器這時還是用的上一次的端口,訪問到服務端后,因為它已經(jīng)重啟了,所以服務端已經(jīng)沒有這個連接的消息了。因此會返回一個RST報文。
【正常請求】:
服務正常啟動,正常發(fā)送請求,這次請求成功,那是當然的,嘿嘿!
這是在mac上用wireshark捕獲的數(shù)據(jù)包,共7個包,前三個包為3次握手的包,第四個包為HTTP層發(fā)送的請求數(shù)據(jù),第五個包為服務端的TCP 確認報文,第六個包為服務端在HTTP層發(fā)送的響應數(shù)據(jù),第七個包為mac對第六個包的確認報文。
重點來關注后面幾個包,先看第四個包: 0x0000: 4500 0295 0000 4000 3606 623b ac17 ccdc
0x0010: 0a60 5cd4 db9b 1ba8 a59a 46ce 6d03 e87d
0x0020: 8018 1015 0ee7 0000 0101 080a 2e4c b2ef
0x0030: 0f20 3acf 4745 5420 2f64 6174 613f 636d
0x0040: 643d 4665 6e63 6532 4172 6561 266d 6574
0x0050: 613d 7b25 3232 6361 6c6c 6572 2532 323a
0x0060: 2532 3274 6573 7425 3232 2c25 3232 5472
0x0070: 6163 6549 6425 3232 3a25 3232 7465 7374
0x0080: 2532 327d 2672 6571 7565 7374 3d7b 2532
0x0090: 3266 656e 6365 2532 323a 5b7b 2532 326c
0x00a0: 6e67 2532 323a 3130 2e32 2c25 3232 6c61
0x00b0: 7425 3232 3a31 302e 327d 2c25 3230 7b25
0x00c0: 3232 6c6e 6725 3232 3a31 302e 322c 2532
0x00d0: 326c 6174 2532 323a 382e 327d 2c25 3230
0x00e0: 7b25 3232 6c6e 6725 3232 3a38 2e32 2c25
0x00f0: 3232 6c61 7425 3232 3a38 2e32 7d2c 2532
0x0100: 307b 2532 326c 6e67 2532 323a 382e 322c
0x0110: 2532 326c 6174 2532 323a 3130 2e32 7d5d
0x0120: 2c25 3232 636f 6f72 6474 7970 6525 3232
0x0130: 3a32 7d20 4854 5450 2f31 2e31 0d0a 486f
0x0140: 7374 3a20 3130 2e39 362e 3932 2e32 3132
0x0150: 3a37 3038 300d 0a55 7067 7261 6465 2d49
0x0160: 6e73 6563 7572 652d 5265 7175 6573 7473
0x0170: 3a20 310d 0a41 6363 6570 743a 2074 6578
0x0180: 742f 6874 6d6c 2c61 7070 6c69 6361 7469
0x0190: 6f6e 2f78 6874 6d6c 2b78 6d6c 2c61 7070
0x01a0: 6c69 6361 7469 6f6e 2f78 6d6c 3b71 3d30
0x01b0: 2e39 2c2a 2f2a 3b71 3d30 2e38 0d0a 5573
0x01c0: 6572 2d41 6765 6e74 3a20 4d6f 7a69 6c6c
0x01d0: 612f 352e 3020 284d 6163 696e 746f 7368
0x01e0: 3b20 496e 7465 6c20 4d61 6320 4f53 2058
0x01f0: 2031 305f 3133 5f36 2920 4170 706c 6557
0x0200: 6562 4b69 742f 3630 352e 312e 3135 2028
0x0210: 4b48 544d 4c2c 206c 696b 6520 4765 636b
0x0220: 6f29 2056 6572 7369 6f6e 2f31 322e 302e
0x0230: 3220 5361 6661 7269 2f36 3035 2e31 2e31
0x0240: 350d 0a41 6363 6570 742d 4c61 6e67 7561
0x0250: 6765 3a20 7a68 2d63 6e0d 0a41 6363 6570
0x0260: 742d 456e 636f 6469 6e67 3a20 677a 6970
0x0270: 2c20 6465 666c 6174 650d 0a43 6f6e 6e65
0x0280: 6374 696f 6e3a 206b 6565 702d 616c 6976
0x0290: 650d 0a0d 0a
我們來逐字節(jié)分析:
剩余的數(shù)據(jù)部分即為TCP協(xié)議相關的。
TCP也是20B固定長度+可變長度部分:
可變長度部分,協(xié)議如下:
剩下來的就是數(shù)據(jù)部分了。我們一行一行地看。
因為http是字符流,所以我們先看一下ascii字符集,執(zhí)行命令: man ascii
可以得到ascii碼,我們直接看十六進制的結果:

把上表的最后一列連起來,就是: GET /data?cmd=Fence2Area&meta={%22caller%22:%22test%22,%22TraceId%22:%22test%22}&request={%22fence%22:[{%22lng%22:10.2,%22lat%22:10.2},%20{%22lng%22:10.2,%22lat%22:8.2},%20{%22lng%22:8.2,%22lat%22:8.2},%20{%22lng%22:8.2,%22lat%22:10.2}],%22coordtype%22:2} HTTP/1.1
Host: 10.96.92.212:7080
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.2 Safari/605.1.15
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
Connection: keep-alive
其中,cr nl表示回車,換行。
docker收到數(shù)據(jù)后,會回復一個ack包。第四個包的總長度為661字節(jié),去掉IP頭部20字節(jié),TCP頭部固定部分20字節(jié),TCP頭部可選長度為12字節(jié),共52字節(jié),因此TCP數(shù)據(jù)部分總長度為661-52=609字節(jié)。另外,序列號為2778351310.
再來看第5個包,字節(jié)流如下: 0x0000: 4500 0034 d28b 4000 4006 8810 0a60 5cd4
0x0010: ac17 ccdc 1ba8 db9b 6d03 e87d a59a 492f
0x0020: 8010 00ec e04e 0000 0101 080a 0f20 3af7
0x0030: 2e4c b2ef
剩余的數(shù)據(jù)部分即為TCP協(xié)議相關的。
TCP也是20B固定長度+可變長度部分:
可變長度部分,協(xié)議如下:
數(shù)據(jù)部分為空,這個包僅為確認包。
再來看第六個包,字節(jié)流如下: 0x0000: 4500 00f9 d28c 4000 4006 874a 0a60 5cd4
0x0010: ac17 ccdc 1ba8 db9b 6d03 e87d a59a 492f
0x0020: 8018 00ec e113 0000 0101 080a 0f20 3af8
0x0030: 2e4c b2ef 4854 5450 2f31 2e31 2032 3030
0x0040: 204f 4b0d 0a41 6363 6573 732d 436f 6e74
0x0050: 726f 6c2d 416c 6c6f 772d 4f72 6967 696e
0x0060: 3a20 2a0d 0a44 6174 653a 2054 6875 2c20
0x0070: 3033 204a 616e 2032 3031 3920 3132 3a32
0x0080: 333a 3437 2047 4d54 0d0a 436f 6e74 656e
0x0090: 742d 4c65 6e67 7468 3a20 3438 0d0a 436f
0x00a0: 6e74 656e 742d 5479 7065 3a20 7465 7874
0x00b0: 2f70 6c61 696e 3b20 6368 6172 7365 743d
0x00c0: 7574 662d 380d 0a0d 0a7b 2264 6174 6122
0x00d0: 3a7b 2261 7265 6122 3a34 3837 3634 3133
0x00e0: 3535 3937 2e38 3432 3630 367d 2c22 6572
0x00f0: 7273 7472 223a 2222 7d
剩余的數(shù)據(jù)部分即為TCP協(xié)議相關的。TCP也是20B固定長度+可變長度部分:
可變長度部分,協(xié)議如下:
剩下來的就是數(shù)據(jù)部分了。我們一行一行地看:
把上表的最后一列連起來,就是: HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Date: Thu, 03 Jan 2019 12:23:47 GMT
Content-Length: 48
Content-Type: text/plain; charset=utf-8
{"data":{"area":48764135597.842606},"errstr":""}
Content-Length: 48,最后一行的長度即為48個字節(jié)。
最后,第七個包,字節(jié)流如下: 0x0000: 4500 0034 0000 4000 3606 649c ac17 ccdc
0x0010: 0a60 5cd4 db9b 1ba8 a59a 492f 6d03 e942
0x0020: 8010 100f 1eb9 0000 0101 080a 2e4c b314
0x0030: 0f20 3af8
剩余的數(shù)據(jù)部分即為TCP協(xié)議相關的。TCP也是20B固定長度+可變長度部分:
可變長度部分,協(xié)議如下:
至此,一次完整的http請求的報文就解析完了。感覺如何,是不是很親切?(PS: WTF?看的人都抓狂了,還親切?哈哈)
5、在應用層學習HTTP協(xié)議
上面我們把HTTP協(xié)議相關的數(shù)據(jù)從2進制層給解密了,下面我將對照上面的數(shù)據(jù)拆解結果,一步步帶你從應用層深入認識HTTP協(xié)議。
5.1 整體介紹
HTTP(Hypertext Transfer Protocol)超文本傳輸協(xié)議,是在互聯(lián)網(wǎng)上進行通信時使用的一種協(xié)議。說得更形象一點:HTTP是現(xiàn)代互聯(lián)網(wǎng)中使用的公共語言。它最著名的應用是用在瀏覽器的服務器間的通信。
HTTP屬于應用層協(xié)議,底層是靠TCP進行可靠地信息傳輸。
HTTP在傳輸一段報文時,會以流的形式將報文數(shù)據(jù)的內(nèi)容通過一條打開的TCP連接按序傳輸。TCP接到上層應用交給它的數(shù)據(jù)流之后,會按序?qū)?shù)據(jù)流打散成一個個的分段。再交到IP層,通過網(wǎng)絡進行傳輸。另一端的接收方則相反,它們將接收到的分段按序組裝好,交給上層HTTP協(xié)議進行處理。
5.2 編碼
我們再來回顧一下:
在之前的報文拆解過程中,我們看到多了很多%22,其實,0x22是單引號"的ascii值。
一方面,URL描述的資源為了能通過其他各種協(xié)議傳送,但是有些協(xié)議在傳輸過程中會剝?nèi)ヒ恍┨囟ǖ淖址?
另一方面,URL還是可讀的,所以那些不可打印的字符就不能在URL中使用了,比如空格;
最后,URL還得是完整的,它需要支持所有語言的字符。
總之,基于很多原因,URL設計者將US-ASCII碼和其轉(zhuǎn)義序列集成到URL中,通過轉(zhuǎn)義序列,就可以用US-ASCII字符集的有限子集對任意字符或數(shù)據(jù)進行編碼了。
轉(zhuǎn)義的方法:百分號(%)后跟著兩個表示ASCII碼的十六進制數(shù)。比如:
所以上面在瀏覽器發(fā)送給服務器的URL進行了非“安全字符”編碼,也就不奇怪了吧?
在URL中,當上面的保留字符用在保留用途之外的場合時,需要對URL進行編碼。
5.3 MIME類型
響應數(shù)據(jù)中,我們注意到有一個首部: Content-Type: text/plain; charset=utf-8
互聯(lián)網(wǎng)上有數(shù)千種不同的數(shù)據(jù)類型,HTTP給每種對象都打上了MIME(Multipurpose Internet Media Extension, 多用途因特網(wǎng)郵件擴展)標簽,也就是響應數(shù)據(jù)中的Content-Type. MIME本來是用在郵件協(xié)議中的,后來被移植到了HTTP中。瀏覽器從服務器上取回了一個對象時,會去查看MIME類型,從而得知如何處理這種對象,是該展示圖片,還是調(diào)用聲卡播放聲音。
MIME通過斜杠來標識對象的主類型和其中的特定的子類型,下表展示了一些常見的類型,其中的實體主體是指body部分:
5.4 URI/URL/URN
URI(Uniform Resource Identifier, 統(tǒng)一資源標識符)表示服務器資源,URL(Uniform Resource Locator, 統(tǒng)一資源定位符)和URN(Uniform Resource Name, 統(tǒng)一資源名)是URI的具體實現(xiàn)。URI是一個通用的概念,由兩個主要的子集URL和URN構成,URL通過位置、URN通過名字來標識資源。
URL定義了資源的位置,表示資源的實際地址,在使用URL的過程中,如果URL背后的資源發(fā)生了位置移動,訪問者就找不到它了。這個時候就要用到URN了,它給定資源一個名字,無論它移動到哪里,都可以通過這個名字來訪問到它,簡直完美!
URL通常的格式是: 協(xié)議方案+服務器地址+具體的資源路徑
協(xié)議方案(scheme),如 http, ftp,告知web客戶端怎樣訪問資源);服務器地址,如 www.oreilly.com ; 具體的資源路徑,如 index.html.
5.5 HTTP方法
HTTP支持幾種不同的請求方法,每種方法對服務器要求的動作不同,如下圖是幾種常見的方法:
HEAD方法只獲取頭部,不獲取數(shù)據(jù)部分。通過頭部可以獲取比如資源的類型(Content-Type)、資源的長度(Content-Length)這些信息。這樣,客戶端可以獲取即將請求資源的一些情況,可以做到心中有數(shù)。 1)POST用于向服務器發(fā)送數(shù)據(jù),常見的是提交表單;
2)PUT用于向服務器上的資源存儲數(shù)據(jù)。
5.6 狀態(tài)碼
每條HTTP的響應報文都會帶上一個三位數(shù)字的狀態(tài)碼和一條解釋性的“原因短語”,通知客戶端本次請求的狀態(tài),幫助客戶端快速理解事務處理結果, 最常見的是: 200 OK
404 Not Found
500 Internal Server Error
我們平時使用瀏覽器的時候,很多的錯誤碼其實是由瀏覽器處理的,我們感知不到。但是404 Not Found會穿透重重迷霧,來到我們面前,為何?那是因為他對我們愛的深沉啊!
客戶端可以據(jù)此狀態(tài)碼,決定下一步的行動(如重定向等)。
三位數(shù)字的第一位表示分類:
5.7 報文格式
HTTP報文實際上是由一行行的字符串組成的,每行字符串的末尾用\r\n分隔,人類可以很方便的閱讀。順便說一句,不是所有的協(xié)議都對人類這么友好的,像thrift協(xié)議,直接甩一堆字節(jié)給你,告訴你說0x0001表示調(diào)用方法,諸如此類的,你只能對著一個十六進制的數(shù)據(jù)塊一個個地去“解碼”。不可能像HTTP協(xié)議這樣,直接將字符編碼,人類可以直接讀懂。
舉個簡單的請求報文和響應報文的格式的例子:
實際上,請求報文也是可以有body(主體)部分的。請求報文是由請求行(request line)、請求頭部(header)、空行、請求數(shù)據(jù)四個部分組成。唯一要注意的一點就是,請求報文即使body部分是空的,請求頭部后的回車換行符也是必須要有的。
響應報文的格式和請求報文的格式類似:
請求報文、響應報文的起始行和響應頭部里的字段都是文本化、結構化的。而請求body卻可以包含任意二進制數(shù)據(jù)(如圖片、視頻、軟件等),當然也可以包含文本。
有些首部是通用的,有些則是請求或者響應報文才會有的。
順便提一下, 用telnet直連服務器的http端口,telnet命令會建立一條TCP通道,然后就可以通過這個通道直接發(fā)送HTTP請求數(shù)據(jù),獲取響應數(shù)據(jù)了。
6、HTTP協(xié)議進階
6.1 代理
HTTP的代理服務器既是Web服務器,又是Web客戶端。
使用代理可以“接觸”到所有流過的HTTP流量,代理可以對其進行監(jiān)視和修改。常見的就是對兒童過濾一些“成人”內(nèi)容;網(wǎng)絡工程師會利用代理服務器來提高安全性,它可以限制哪些應用層的協(xié)議數(shù)據(jù)可以通過,過濾“病毒”等數(shù)據(jù);代理可以存儲緩存的文件,直接返回給訪問者,無需請求原始的服務器資源;對于訪問慢速網(wǎng)絡上的公共內(nèi)容時,可以假扮服務器提供服務,從而提高訪問速度;這被稱為反向代理;可以作為內(nèi)容路由器,如對付費用戶,則將請求導到緩存服務器,提高訪問速度;可以將頁面的語言轉(zhuǎn)換到與客戶端相匹配,這稱為內(nèi)容轉(zhuǎn)碼器; 匿名代理會主動從HTTP報文中刪除身份相關的信息,如User-Agent, Cookie等字段。
現(xiàn)實中,請求通過以下幾種方式打到代理服務器上去:
報文每經(jīng)過一個中間點(代理或網(wǎng)關),都需要在首部via字段的末尾插入一個可以代表本節(jié)點的獨特的字符串,包含實現(xiàn)的協(xié)議版本和主機地址。注意下圖中的via字段。
請求和響應的報文傳輸路徑通常都是一致的,只不過方向是相反的。因此,響應報文上的via字段表示的中間節(jié)點的順序是剛好相反的。
6.2 緩存
當有很多請求訪問同一個頁面時,服務器會多次傳輸同一份數(shù)據(jù),這些數(shù)據(jù)重復地在網(wǎng)絡中傳輸著,消耗著大量帶寬。如果將這些數(shù)據(jù)緩存下來,就可以提高響應速度,節(jié)省網(wǎng)絡帶寬了。
大部分緩存只有在客戶端發(fā)起請求,并且副本已經(jīng)比較舊的情況下才會對副本的新鮮度進行檢測。最常用的請求首部是If-Modified-Since, 如果在xx時間(此時間即為If-Modified-Since的值)之后內(nèi)容沒有變化,服務器會回應一個304 Not Modified. 否則,服務器會正常響應,并返回原始的文件數(shù)據(jù),而這個過程中被稱為再驗證命中。
再驗證可能出現(xiàn)命中或未命中的情況: 1)未命中時,服務器回復200 OK,并且返回完整的數(shù)據(jù);
2)命中時,服務器回復304 Not Modified。
還有一種情況,緩存被刪除了,那么根據(jù)響應狀態(tài)碼,緩存服務器也會刪除自己緩存的副本。
順帶提一句,若要在項目中使用緩存,就一定要關注緩存命中比例。若命中比例不高,就要重新考慮設置緩存的必要性了。
緩存服務器返回響應的時候,是基于已緩存的服務器響應的首部,再對一些首部字段做一些微調(diào)。比如向其中插入新鮮度信息(如Age, Expires首部等),而且通常會包含一個via首部來說明緩存是由一個緩存代理提供的。注意,這時不要修改Date字段,它表示原始服務器最初構建這條響應的日期。
HTTP通過文檔過期機制和服務器再驗證機制保持已緩存數(shù)據(jù)和服務器間的數(shù)據(jù)充分一致。
文檔過期通過如下首部字段來表示緩存的有效期:
當上面兩個字段暗示的過期時間已到,需要向服務器再次驗證文檔的新鮮度。如果這時緩存仍和服務器上的原始文檔一致,緩存只需要更新頭部的相關字段。如上表中提到的Expires字段等。
為了更好的節(jié)省網(wǎng)絡流量,緩存服務器可以通過相關首部向原始服務器發(fā)送一個條件GET請求, 這樣只有在緩存真正過期的情況下,才會返回原始的文檔,否則只會返回相關的首部。
條件GET請求會用到如下的字段:
6.3 cookie
cookie是服務器“貼在”客戶端身上的標簽,由客戶端維護的狀態(tài)片段,并且只會回送給合適的站點。
有兩類cookie: 1)會話cookie、持久cookie. 會話cookie在退出瀏覽器后就被刪除了;
2)而持久cookie則保存在硬盤中,計算機重啟后仍然存在。
服務器在給客戶端的響應字段首部加上Set-cookie或Set-cookie2, 值為名字=值的列表,即可以包含多個字段。當下次瀏覽器再次訪問到相同的網(wǎng)站時,會將這些字段通過Cookie帶上。cookie中保留的內(nèi)容是服務器給此客戶端打的標簽,方便服務進行追蹤的識別碼。瀏覽器會將cookie以特定的格式存儲在特定的文件中。
瀏覽器只會向產(chǎn)生這條cookie的站點發(fā)生cookie. Set-cookie字段的值會包含domain這個字段,告知瀏覽器可以把這條cookie發(fā)送給給相關的匹配的站點。path字段也是相似的功能。
如i瀏覽器收到如下的cookie: Set-cookie: user="mary"; domain="stefno.com"
那么瀏覽器在訪問任意以stefno.com結尾的站點都會發(fā)送: Cookie: user="mary"
6.4 實體和編碼
響應報文中的body部分傳輸?shù)臄?shù)據(jù)本質(zhì)上都是二進制。我們從上面的報文數(shù)據(jù)也可以看出來,都是用十六進制數(shù)來表示,關鍵是怎么解釋這塊內(nèi)容。
如果Content-Type定義是text/plain, 那說明body內(nèi)容就是文本,我們直接按文本編碼來解釋;如果Content-Type定義是image/png, 說明body部分是一幅圖片,那我們就按圖片的格式去解釋數(shù)據(jù)。
Content-Length標示報文主體部分的數(shù)據(jù)長度大小,如果內(nèi)容是壓縮的,那它表示的就是壓縮后的大小。另外,Content-Length在長連接的情況下,可以對多個報文進行正確地分段。所以,如果沒有采用分塊編碼,響應數(shù)據(jù)中必須帶上Content-Length字段。分塊編碼的情形中,數(shù)據(jù)被拆分成很多小塊,每塊都有大小說明。因此,任何帶有主體部分的報文(請求或是響應)都應帶上正確的Content-Length首部。
HTTP的早期版本采用關閉連接的方式來劃定報文的結束。這帶來的問題是顯而易見的:客戶端并不能分清是因為服務器正常結束還是中途崩潰了。這里,如果是客戶端用關閉來表示請求報文主體部分的結束,是不可取的,因為關閉之后,就無法獲取服務器的響應了。當然,客戶端可以采用半關閉的方式,只關閉數(shù)據(jù)發(fā)送方向,但是很多服務器是不識別的,會把半關閉當成客戶端要成服務器斷開來處理。
HTTP報文在傳輸?shù)倪^程中可能會遭到代理或是其他通信實體的無意修改,為了讓接收方知道這種情況,服務器會對body部分作一個md5, 并把值放到Content-MD5這個字段中。但是,如果中間的代理即修改了報文主體,又修改了md5, 就不好檢測了。因此規(guī)定代理是不能修改Content-MD5首部的。這樣,客戶端在收到數(shù)據(jù)后,先進行解碼,再算出md5, 并與Content-MD5首部進行比較。這主要是防止代理對報文進行了無意的改動。
HTTP在發(fā)送內(nèi)容之前需要對其進行編碼,它是對報文主體進行的可逆變換。比如將報文用gzip格式進行壓縮,減少傳輸時間。
常見的編碼類型如下:
當然,客戶端為了避免服務器返回自己不能解碼的數(shù)據(jù),請求的時候,會在Accept-Encoding首部里帶上自己支持的編碼方式。如果不傳輸?shù)脑?默認可以接受任何編碼方式。
上面提到的編碼是內(nèi)容編碼,它只是在響應報文的主體報文將原始數(shù)據(jù)進行編碼,改變的是內(nèi)容的格式。還有另一種編碼:傳輸編碼。它與內(nèi)容無關,它是為了改變報文數(shù)據(jù)在網(wǎng)絡上傳輸?shù)姆绞健鬏斁幋a是在HTTP 1.1中引入的一個新特性。
通常,服務器需要先生成數(shù)據(jù),再進行傳輸,這時,可以計算數(shù)據(jù)的長度,并將其編碼到Content-Length中。但是,有時,內(nèi)容是動態(tài)生成的,服務器希望在數(shù)據(jù)生成之前就開始傳輸,這時,是沒有辦法知道數(shù)據(jù)大小的。這種情況下,就要用到傳輸編碼來標注數(shù)據(jù)的結束的。
HTTP協(xié)議中通過如下兩個首部來描述和控制傳輸編碼:
分塊編碼的報文形式是這樣的:
每個分塊包含一個長度值(十六進制,字節(jié)數(shù))和該分塊的數(shù)據(jù)。用于區(qū)隔長度值和數(shù)據(jù)。長度值不包含分塊中的任何序列。最后一個分塊,用長度值0來表示結束。注意報文首部包含一個Trailer: Content-MD5, 所以在緊跟著最后一個報文結束之后,就是一個拖掛。其他如,Content-Length, Trailer, Transfer-Encoding也可以作為拖掛。
內(nèi)容編碼和傳輸編碼是可以結合起來使用的。
6.5 國際化支持
HTTP為了支持國際化的內(nèi)容,客戶端要告知服務器自己能理解的何種語言,以及瀏覽器上安裝了何種字母表編碼算法。這通過Accept-Charset和Accept-Language首部實現(xiàn)。
比如: Accept-Language: fr, en;q=0.8
Accept-Charset: iso-8859-1, utf-8
表示: 客戶端接受法語(fr, 優(yōu)先級默認為1.0)、英語(en, 優(yōu)先級為0.8),支持iso-8859-1, utf-8兩種字符集編碼。服務器則會在Content-Type首部里放上charset.
本質(zhì)上,HTTP報文的body部分存放的就是一串二進制碼,我們先把二進制碼轉(zhuǎn)換成字符代碼(如ascii是一個字節(jié)表示一個字符,而utf-8則表示一個字符的字節(jié)數(shù)不定,每個字符1~6個字節(jié)),之后,用字符代碼去字符集中找到對應的元素。
比較常見的字符集是US-ASCII: 這個字符集是所有字符集的始祖,早在1968年就發(fā)布了標準。ASCII碼的代碼值從0到127, 只需要7個bit位就可以覆蓋代碼空間。HTTP報文的首部、URL使用的字符集就是ASCII碼??梢栽倏聪律衔膱笪姆治霾糠值腶csii碼集。
US-ASCII是把每個字符編碼成固定的7位二進制值。UTF-8則是無固定的編碼方案。第一個字節(jié)的高位用來表示編碼后的字符所用的字節(jié)數(shù)(如果所用的字節(jié)數(shù)是5,則第一個字節(jié)前5bit都是1,第6bit是0),所需的后續(xù)的字節(jié)都含有6位的代碼值,前兩個bit位是用10標識。
舉個例子,漢字“嚴”的Unicode編碼為4E25(100111000100101), 共有15位,落在上表中的第三行,因此“嚴”的編碼就需要三個字節(jié)。將100111000100101填入上表中的c位即可。因此,嚴的UTF-8編碼是11100100 10111000 10100101,轉(zhuǎn)換成十六進制就是E4B8A5. 比如我在谷歌搜索框里搜索“嚴”字,google發(fā)出的請求如下: https://www.google.com.hk/search?q=%E4%B8%A5&oq=%E4%B8%A5&aqs=chrome..69i57j0l5.3802j0j4&sourceid=chrome&ie=UTF-8&gws_rd=cr
q=%E4%B8%A5 這個就是搜索的詞了。
6.6 重定向與負載均衡
Web內(nèi)容通常分散地分布在很多地方,這可以防止“單點故障”,萬一某個地方發(fā)生地震了,機房被毀了,那還有其他地方的機房可以提供服務。一般都會有所謂的“雙活”,“多活”,所謂狡兔三窟嘛。
這樣,用戶的請求會根據(jù)負載均衡的原則,被重定向到它應該去的地方。
HTTP重定向:
服務器收到客戶端請求后,向客戶端返回一條帶有狀態(tài)碼302重定向的報文,告訴他們應該去其他的地方試試。web站點將重定向看成一種簡單的負載均衡策略來使用,重定向服務器找到可用的負載最小的機器,由于服務器知道客戶端的地址,理論上來說,可以做到最優(yōu)的重定向選擇。
當然,缺點也是顯而易見的,由于客戶端要發(fā)送兩次請求,因此會增加耗時。
DNS重定向:
DNS將幾個IP地址關聯(lián)到一個域上,采用算法決定返回的IP地址。可以是簡單的輪轉(zhuǎn);也可以是更高級的算法,如返回負載最輕的服務器的IP地址,稱為負載均衡算法;如果考慮地理位置,返回給客戶端最近位置的地址,稱為鄰接路由算法;還有一種是繞過出現(xiàn)故障的地址,稱為故障屏蔽算法。
DNS服務器總是會返回所有的IP地址,但是DNS客戶端一般只會使用第一個IP地址,而且會緩存下來,之后會一直用這個地址。所以,DNS輪轉(zhuǎn)通常不會平衡單個客戶端的負載。但是,由于DNS服務器對于不同的請求,總是會返回輪轉(zhuǎn)后的IP地址列表,因此,會把負載分散到多個客戶端。
6.7 HTTP連接
HTTP連接是HTTP報文傳輸?shù)年P鍵通道。
【并行連接】:
對于一個頁面上同時出現(xiàn)多個對象的時候,如果瀏覽器并行地打開多個連接,同時去獲取這些對象,多個連接的TCP握手時延可以進行重疊,速度會快起來。
如一個包含3張圖片的頁面,瀏覽器要發(fā)送4次HTTP請求來獲取頁面。1個用于頂層的HTML頁面,3個用于圖片。
如果采用串行方式,那么連接時延會進行疊加:
采用并行連接之后:
但是并行連接也不絕對提升速度,如果一個頁面有數(shù)百個內(nèi)嵌對象,那要啟動數(shù)百個連接,對服務器的性能也是非常大的挑戰(zhàn)。所以,通常瀏覽器會限制并行連接的總數(shù)據(jù)在一個較小的值,通常是4個,而且服務端可以隨意關閉客戶端超量的連接。
另一方面,如果客戶端網(wǎng)絡帶寬較小,每個連接都會去爭搶有限的帶寬,每個連接都會獲取較小的速度,即每個對象都會以較小的速度去加載。這樣,并行連接帶來的速度提升就會比較小,甚至沒有提升。
【持久連接】:
持久連接即HTTP的keep-alive機制。
我們知道HTTP請求是“請求-應答”模式,每次請求-應答都要新建一個連接,完成之后要斷開連接。HTTP是無狀態(tài)的,連接之間沒有任何關系。
HTTP是應用層協(xié)議,TCP是傳輸層協(xié)議。HTTP底層仍然采用TCP進行傳輸數(shù)據(jù)。TCP為HTTP提供了一層可靠的比特傳輸通道。HTTP一般交換的數(shù)據(jù)都不大,而每次連接都要進行TCP三次握手,很大一部分時間都消耗在這上面,有時候甚至能達到50%。如果能復用連接,就可以減少由于TCP三次握手所帶來的時延。
HTTP 1.1默認開啟keep-alive機制,從上面抓到的包也可以看到。這樣,數(shù)據(jù)傳輸完成之后保持TCP連接不斷開,之后同域名下復用連接,繼續(xù)用這個通道傳輸數(shù)據(jù)。服務器在響應一個請求后,可以保持這個連接keep-alive timeout的時間,在這個時間內(nèi)沒有請求,則關閉此連接;否則,重新開始倒計時keep-alive timeout時間。
HTTP有keep-alive機制,目的是可以在一個TCP連接上傳輸多個HTTP事務,以此提高通信效率。底層的TCP其實也有keep-alive機制,它是為了探測TCP連接的活躍性。TCP層的keepalive可以在任何一方設置,可以是一端設置、兩端同時設置或者兩端都沒有設置。新建socket的時候需要設置,從而使得協(xié)議棧調(diào)用相關函數(shù)tcp_set_keepalive,來激活連接的keep-alive屬性。
當網(wǎng)絡兩端建立了TCP連接之后,閑置(雙方?jīng)]有任何數(shù)據(jù)流發(fā)送往來)時間超過tcp_keepalive_time后,服務器內(nèi)核就會嘗試向客戶端發(fā)送偵測包,來判斷TCP連接狀況(有可能客戶端崩潰、強制關閉了應用、主機不可達等等)。如果沒有收到對方的回答(ack包),則會在 tcp_keepalive_intvl后再次嘗試發(fā)送偵測包,直到收到對方的ack,如果一直沒有收到對方的ack,一共會嘗試 tcp_keepalive_probes次,每次的間隔時間在這里分別是15s, 30s, 45s, 60s, 75s。如果嘗試tcp_keepalive_probes次后,依然沒有收到對方的ack包,則會丟棄該TCP連接。TCP連接默認閑置時間是2小時,一般設置為30分鐘足夠了。
【管道化連接】:
在keep-alive的基礎上,我們可以做地更進一步,在響應到達之前,我們將多條請求按序放入請求隊列,服務端在收到請求后,必須按照順序?qū)埱蟮捻憫5捎诰W(wǎng)絡環(huán)境非常復雜,因此即使請求是按順序發(fā)送的,也不一定是按順序到達服務端的。而且就算是服務端按序處理的,也不一定是按序返回給客戶端,所以最好是在響應中附帶一些可以標識請求的參數(shù)。
為了安全起見,管道化的連接只適合“冪等”的請求,一般我們認為:GET/HEAD/PUT/DELETE/TRACE/OPTIONS等方法都是冪等的。
7、本文小結
以上,就是所有HTTP的通信細節(jié)了,足夠在日常開發(fā) 作中使用了。更多沒有涉及的細節(jié)可以在用到的時候再去仔細研究。
文章看完了,不知道你對HTTP的理解有沒有更上一層樓?歡迎一起交流探討。
8、參考資料 [1]【http長連接】 https://www.cnblogs.com/cswuyg/p/3653263.html
[2]【http/tcp keep alive】 https://segmentfault.com/a/1190000012894416
[3]【http/tcp keep alive】 http://www.nowamagic.net/academy/detail/23350305
[4]【http/tcp keep alive】 https://laravel-china.org/articl ... n-the-http-protocol
[5]【tcp keep alive】 http://blog.51cto.com/zxtong/1788252
[6]【http權威指南】 https://book.douban.com/subject/10746113/
[7]【HTTP狀態(tài)碼】 https://www.cnblogs.com/starof/p/5035119.html
[8]【HTTP協(xié)議】 https://www.cnblogs.com/ranyonsue/p/5984001.html
[9]【HTTP狀態(tài)分類】 http://www.runoob.com/http/http-status-codes.html
[10]【url編碼】 http://www.ruanyifeng.com/blog/2010/02/url_encoding.html
附錄:更多網(wǎng)絡編程文章 《 TCP/IP詳解 - 第11章·UDP:用戶數(shù)據(jù)報協(xié)議 》
《 TCP/IP詳解 - 第17章·TCP:傳輸控制協(xié)議 》
《 TCP/IP詳解 - 第18章·TCP連接的建立與終止 》
《 TCP/IP詳解 - 第21章·TCP的超時與重傳 》
《 技術往事:改變世界的TCP/IP協(xié)議(珍貴多圖、手機慎點) 》
《 通俗易懂-深入理解TCP協(xié)議(上):理論基礎 》
《 通俗易懂-深入理解TCP協(xié)議(下):RTT、滑動窗口、擁塞處理 》
《 理論經(jīng)典:TCP協(xié)議的3次握手與4次揮手過程詳解 》
《 理論聯(lián)系實際:Wireshark抓包分析TCP 3次握手、4次揮手過程 》
《 計算機網(wǎng)絡通訊協(xié)議關系圖(中文珍藏版) 》
《 UDP中一個包的大小最大能多大? 》
《 P2P技術詳解(一):NAT詳解——詳細原理、P2P簡介 》
《 P2P技術詳解(二):P2P中的NAT穿越(打洞)方案詳解 》
《 P2P技術詳解(三):P2P技術之STUN、TURN、ICE詳解 》
《 通俗易懂:快速理解P2P技術中的NAT穿透原理 》
《 高性能網(wǎng)絡編程(一):單臺服務器并發(fā)TCP連接數(shù)到底可以有多少 》
《 高性能網(wǎng)絡編程(二):上一個10年,著名的C10K并發(fā)連接問題 》
《 高性能網(wǎng)絡編程(三):下一個10年,是時候考慮C10M并發(fā)問題了 》
《 高性能網(wǎng)絡編程(四):從C10K到C10M高性能網(wǎng)絡應用的理論探索 》
《 高性能網(wǎng)絡編程(五):一文讀懂高性能網(wǎng)絡編程中的I/O模型 》
《 高性能網(wǎng)絡編程(六):一文讀懂高性能網(wǎng)絡編程中的線程模型 》
《 技術掃盲:新一代基于UDP的低延時網(wǎng)絡傳輸層協(xié)議——QUIC詳解 》
《 讓互聯(lián)網(wǎng)更快:新一代QUIC協(xié)議在騰訊的技術實踐分享 》
《 現(xiàn)代移動端網(wǎng)絡短連接的優(yōu)化手段總結:請求速度、弱網(wǎng)適應、安全保障 》
《 聊聊iOS中網(wǎng)絡編程長連接的那些事 》
《 移動端IM開發(fā)者必讀(一):通俗易懂,理解移動網(wǎng)絡的“弱”和“慢” 》
《 移動端IM開發(fā)者必讀(二):史上最全移動弱網(wǎng)絡優(yōu)化方法總結 》
《 IPv6技術詳解:基本概念、應用現(xiàn)狀、技術實踐(上篇) 》
《 IPv6技術詳解:基本概念、應用現(xiàn)狀、技術實踐(下篇) 》
《 從HTTP/0.9到HTTP/2:一文讀懂HTTP協(xié)議的歷史演變和設計思路 》
《 以網(wǎng)游服務端的網(wǎng)絡接入層設計為例,理解實時通信的技術挑戰(zhàn) 》
《 邁向高階:優(yōu)秀Android程序員必知必會的網(wǎng)絡基礎 》
《 全面了解移動端DNS域名劫持等雜癥:技術原理、問題根源、解決方案等 》
《 美圖App的移動端DNS優(yōu)化實踐:HTTPS請求耗時減小近半 》
《 Android程序員必知必會的網(wǎng)絡通信傳輸層協(xié)議——UDP和TCP 》
《 IM開發(fā)者的零基礎通信技術入門(一):通信交換技術的百年發(fā)展史(上) 》
《 IM開發(fā)者的零基礎通信技術入門(二):通信交換技術的百年發(fā)展史(下) 》
《 IM開發(fā)者的零基礎通信技術入門(三):國人通信方式的百年變遷 》
《 IM開發(fā)者的零基礎通信技術入門(四):手機的演進,史上最全移動終端發(fā)展史 》
《 IM開發(fā)者的零基礎通信技術入門(五):1G到5G,30年移動通信技術演進史 》
《 IM開發(fā)者的零基礎通信技術入門(六):移動終端的接頭人——“基站”技術 》
《 IM開發(fā)者的零基礎通信技術入門(七):移動終端的千里馬——“電磁波” 》
《 IM開發(fā)者的零基礎通信技術入門(八):零基礎,史上最強“天線”原理掃盲 》
《 IM開發(fā)者的零基礎通信技術入門(九):無線通信網(wǎng)絡的中樞——“核心網(wǎng)” 》
《 IM開發(fā)者的零基礎通信技術入門(十):零基礎,史上最強5G技術掃盲 》
《 IM開發(fā)者的零基礎通信技術入門(十一):為什么WiFi信號差?一文即懂! 》
《 IM開發(fā)者的零基礎通信技術入門(十二):上網(wǎng)卡頓?網(wǎng)絡掉線?一文即懂! 》
《 IM開發(fā)者的零基礎通信技術入門(十三):為什么手機信號差?一文即懂! 》
《 IM開發(fā)者的零基礎通信技術入門(十四):高鐵上無線上網(wǎng)有多難?一文即懂! 》
《 IM開發(fā)者的零基礎通信技術入門(十五):理解定位技術,一篇就夠 》
>> 更多同類文章 ……
(本文同步發(fā)布于: http://www.52im.net/thread-2456-1-1.html )
技術問答
2019-04-13 11:27:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>

問題描述
其實問題來源是我在進行搭建簡易服務器的時候出現(xiàn)的,在調(diào)試過程中我發(fā)現(xiàn)每一次訪問url,通過 client = server.accept();

都會接收到除了正常連接進來的外,一個沒有數(shù)據(jù)傳輸?shù)目蛻舳藄ocket,對上面接收到的socket,進行下面操作為結果為空。 client.getInputStream()

這里請求url的方式用的是postman,不是用的瀏覽器,所有可以排除掉瀏覽器對各種css,js,favicon.ico的請求,
如下圖,是我發(fā)起的一個/login請求:
這里訪問的是我上面提到的簡易服務器,服務器采用的是BIO模式實現(xiàn)的短連接,并且在檢查到`client.getInputStream()==null`后關閉了客戶機的socket。
如上圖中,深色區(qū)域內(nèi)客戶機端口號為32623的報文段,就是我指的未知的TCP連接,未標深色的端口號為:32624就是正常的訪問/login的TCP請求。
可以看到這個特殊的socket,沒有傳輸任何數(shù)據(jù),而且連接后立即關閉了
(這里我在服務端確實在判斷了其輸入流為空后對其socket進行了close操作,但是報文端顯示它卻是從客戶端先發(fā)起的,所以現(xiàn)在也不確定它是我在服務端造成立即關閉,還是客戶端造成的)

然后我考慮到是否是由于我服務器代碼的某個bug造成的,然后我測試了本機的一個JavaWeb項目,以Tomcat作為服務器,我再次進行抓包,得到如下結果:


上圖發(fā)現(xiàn),還是有這么一個特殊的TCP連接,這似乎存在著共性,并且特殊請求的端口和正常請求的端口號是相連的。
所有我考慮這難道是什么來自協(xié)議或者什么的約束? 哎,學淺!
查了一些資料,未果。
于是尋求各路大俠幫助!答疑解惑,感謝!
技術問答
2019-03-24 10:02:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
同樣的請求 在 Wireshark的 界面 看到 4個連接

然后追蹤流,又變成了 2個 ,什么意思?

并且 用 Charles 觀察 ,有5個。。。就不說 那兩個文件 了,就第一個 .ashx 的鏈接 怎么丟了呢?
Charles 是用手機請求的;ws 是 觀察的模擬器的,但我確定 點的是一個連接,是這個原因嗎?
技術問答
2016-10-27 10:41:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
我是tomcat7,通過keytool生成了keystore,自簽名,配置了8443端口,能夠https訪問,瀏覽器也提示了不安全,說明正常,但是我通過wireshark抓包并不能看到握手過程,請問各位是還要配置什么嗎?
技術問答
2018-04-17 11:30:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
本手冊介紹: 介紹Wireshark安裝、界面、基本操作
詳細清單如下:
目錄 譯者序 1. 為什么要翻譯 2. 關于本手冊 2.1. 用什么工具編寫的 2.2. 手冊翻譯的效果 2.3. 翻譯中的問題 3. 補充說明 前言 1. 序言 2. 本書的閱讀對象 3. 感謝 4. 文檔約定 5. 如何獲得本書最新版本? 6. 反饋 1. 介紹 1.1. 什么是Wireshark 1.1.1. 主要應用 1.1.2. 特性 1.1.3. 捕捉多種網(wǎng)絡接口 1.1.4. 支持多種其它程序捕捉的文件 1.1.5. 支持多格式輸出 1.1.6. 對多種協(xié)議解碼提供支持 1.1.7. 開源軟件 1.1.8. Wireshark不能做的事 1.2. 系通需求 1.2.1. 一般說明 1.2.2. Microsoft Windows 1.2.3. Unix/Linux 1.3. 從哪里可以得到Wireshark 1.4. Wiresahrk簡史 1.5. Wireshark開發(fā)維護 1.6. 匯報問題和獲得幫助 1.6.1. 網(wǎng)站 1.6.2. 百科全書 1.6.3. FAQ 1.6.4. 郵件列表 1.6.5. 報告問題 1.6.6. 在UNIX/Linux平臺追蹤軟件錯誤 1.6.7. 在Windows平臺追蹤軟件錯誤 2. 編譯/安裝Wireshark 2.1. 須知 2.2. 獲得源 2.3. 在UNIX下安裝之前 2.4. 在UNIX下編譯Wireshark 2.5. 在UNIX下安裝二進制包 2.5.1. 在Linux或類似環(huán)境下安裝RPM包 2.5.2. 在Debian環(huán)境下安裝Deb包 2.5.3. 在Gentoo Linux環(huán)境下安裝Portage 2.5.4. 在FreeBSD環(huán)境下安裝包 2.6. 解決UNIX下安裝過程中的問題 2.7. 在Windows下編譯源 2.8. 在Windows下安裝Wireshark 2.8.1. 安裝Wireshark 2.8.2. 手動安裝WinPcap 2.8.3. 更新Wireshark 2.8.4. 更新WinPcap 2.8.5. 卸載Wireshark 2.8.6. 卸載WinPcap 3. 用戶界面 3.1. 須知 3.2. 啟動Wireshark 3.3. 主窗口 3.3.1. 主窗口概述 3.4. 主菜單 3.5. "File"菜單 3.6. "Edit"菜單 3.7. "View"菜單 3.8. "Go"菜單 3.9. "Capture"菜單 3.10. "Analyze"菜單 3.11. "Statistics"菜單 3.12. "Help"菜單 3.13. "Main"工具欄 3.14. "Filter"工具欄 3.15. "Pcaket List"面板 3.16. "Packet Details"面板 3.17. "Packet Byte"面板 3.18. 狀態(tài)欄 4. 實時捕捉數(shù)據(jù)包 4.1. 介紹 4.2. 準備工作 4.3. 開始捕捉 4.4. 捕捉接口對話框 4.5. 捕捉選項對話框 4.5.1. 捕捉楨 4.5.2. 捉數(shù)據(jù)幀為文件。 4.5.3. 停止捕捉楨 4.5.4. 顯示楨選項 4.5.5. 名稱解析設置 4.5.6. 按鈕 4.6. 捕捉文件格式、模式設置 4.7. 鏈路層包頭類型 4.8. 捕捉時過濾 4.8.1. 自動過濾遠程通信 4.9. 在捕捉過程中 4.9.1. 停止捕捉 4.9.2. 重新啟動捕捉 5. 文件輸入/輸出及打印 5.1. 說明 5.2. 打開捕捉文件 5.2.1. 打開捕捉文件對話框 5.2.2. 輸入文件格式 5.3. 保存捕捉包 5.3.1. "save Capture File As/保存文件為"對話框 5.3.2. 輸出格式 5.4. 合并捕捉文件 5.4.1. 合并文件對話框 5.5. 文件集合 5.5.1. 文件列表對話框 5.6. 導出數(shù)據(jù) 5.6.1. "Export as Plain Text File"對話框 5.6.2. "Export as PostScript File" 對話框 5.6.3. "Export as CSV (Comma Separated Values) File" 對話框 5.6.4. "Export as PSML File" 對話框 5.6.5. "Export as PDML File" 對話框 5.6.6. "Export selected packet bytes" 對話框 5.6.7. "Export Objects" 對話框 5.7. 打印包 5.7.1. 打印 對話框 5.8. 包范圍選項 5.9. 包格式選項 6. 處理已經(jīng)捕捉的包 6.1. 瀏覽您捕捉的包 6.2. 彈出菜單項 6.2.1. 包列表面板的彈出菜單 6.2.2. 包詳情面板的彈出菜單 6.3. 瀏覽時過濾包 6.4. 建立顯示過濾表達式 6.4.1. 顯示過濾字段 6.4.2. 比較值 6.4.3. 組合表達式 6.4.4. 常見的錯誤 6.5. “Filter Expression/過濾表達式”對話框 6.6. 定義,保存過濾器 6.7. 查找包 6.7.1. 查找包對話框 6.7.2. "Find Next/查找下一個"命令 6.7.3. "Find Previous/查找上一個"命令 6.8. 到指定的包 6.8.1. "GO Back"返回命令 6.8.2. "Go Forward /向前"命令 6.8.3. "Go to Packet/到指定的包"對話框 6.8.4. "Go to Corresponding Packet/到對應的包"命令 6.8.5. "Go to Firest Packet/到第一個包"命令 6.8.6. "Go to Last Packet/到最后一個包"命令 6.9. 標記包 6.10. 時間顯示格式及參考時間 6.10.1. 包參考時間 7. 高級 7.1. 說明 7.2. "Follow TCP Stream" 7.2.1. "Follow TCP Stream"對話框 7.3. 時間戳 7.3.1. Wireshark內(nèi)置 7.3.2. 捕捉文件格式 7.3.3. 準確性 7.4. 時區(qū) 7.4.1. 正確設置你的計算機的時區(qū) 7.4.2. Wireshark和時區(qū)的關系 7.5. 重組包 7.5.1. 什么是重組包 7.5.2. 如何用Wireshark重組包 7.6. 名稱解析 7.6.1. 名字解析的流弊 7.6.2. 以太網(wǎng)名字解析(mac層) 7.6.3. IP地址解析(網(wǎng)絡層) 7.6.4. IPX名稱解析(網(wǎng)絡層) 7.6.5. TCP/UDP端口名解析(傳輸層) 7.7. 校檢和 7.7.1. Wireshark校檢和驗證 7.7.2. Checksum offloading 8. 統(tǒng)計 8.1. 說明 8.2. 摘要窗口 8.3. "Protocol Hierarchy"窗口 8.4. "Endpoints" 8.4.1. 什么是Endpoint? 8.4.2. "Endpoints"窗口 8.4.3. 特定協(xié)議的"Endpoint List"窗口 8.5. 會話/conversations 8.5.1. 什么是會話/conversation? 8.5.2. "Conversations/會話" window 8.5.3. 協(xié)議指定“Conversation List/會話列表”窗口 8.6. "IO Graphs"窗口 8.7. 服務相應時間 8.7.1. "Service Response Time DCE-RPC"窗口 8.8. 協(xié)議指定統(tǒng)計窗口 9. 個性化Wireshark 9.1. 說明 9.2. 從命令行啟動Wireshark 9.3. 包色彩顯示設置 9.4. 設置協(xié)議解碼 9.4.1. "Enable Protocols"對話框 9.4.2. 用戶指定解碼器 9.4.3. 顯示用戶指定解碼器 9.5. 首選項 9.6. 用戶表表 9.7. 創(chuàng)建過濾宏 9.8. Tektronics K12xx/15 RF5 協(xié)議表 9.9. 用戶 DLTs 協(xié)議表 9.10. SNMP用戶表
插圖清單 1.1. Wireshark捕捉包并允許您檢視其內(nèi)容 3.1. 主窗口界面 3.2. 主菜單 3.3. File菜單 3.4. "Edit"菜單 3.5. "View"菜單 3.6. "GO"菜單 3.7. "Capture"菜單 3.8. "Analyze"菜單 3.9. "Statistics"菜單 3.10. 幫助菜單 3.11. 3.12. 過濾工具欄 3.13. "Packet list/包列表"面板 3.14. "Packet Details/包詳情"面板 3.15. Packet Byte/包字節(jié)面板 3.16. 帶選項的"Paket Bytes/包字節(jié)"面板 3.17. 初始狀態(tài)欄 3.18. 載入文件后的狀態(tài)欄 3.19. 已選擇協(xié)議字段的狀態(tài)欄 4.1. "Capture Interfaces"捕捉接口對話框 4.2. "Capture Option/捕捉選項"對話框 4.3. 捕捉信息對話框 5.1. Windows下的打開對話框 5.2. 新版GtK下的打開對話框 5.3. 舊版GTK下的打開對話框 5.4. Windows下的保存為對話框 5.5. 新版GtK下的保存為對話框 5.6. 舊版GTK下的保存為對話框 5.7. Windows下的"合并"對話框 5.8. 新版GtK下的合并話框 5.9. 舊版GTK下的合并對話框 5.10. 文件列表對話框 5.11. "Export as Plain Text File"對話框 5.12. "Export as PostScript File" 對話框 5.13. "Export as PSML File"對話框 5.14. "Export as PDML File"對話框 5.15. "Export Selected Packet Bytes" 對話框 5.16. "Export Objects"對話框 5.17. "Print" 對話框 5.18. "Packet Range"選項卡 5.19. "Packet Format"選項卡 6.1. Wireshark選擇了一個TCP包后的界面 6.2. 在分離窗口瀏覽包 6.3. 包列表面板彈出菜單 6.4. 包詳情面板彈出上下文菜單項 6.5. 用TCP協(xié)議過濾 6.6. 過濾表達式對話框 6.7. "捕捉過濾器"和"顯示過濾器"對話框 6.8. "Find Packet/查找包"對話框 6.9. "GO to packet/轉(zhuǎn)到指定包"對話框 6.10. 時間參考舉例 7.1. "Follow TCP Stream"對話框 8.1. "Summary" 窗口 8.2. "Protocol Hierarchy" 窗口 8.3. "Endpoints"窗口 8.4. "Conversations"對話框 8.5. "IO Graphs" 窗口 8.6. "Compute DCE-RPC statistics"窗口 8.7. The "DCE-RPC Statistic for ..." 窗口 9.1. "Coloring Rules"對話框 9.2. "Edit Color Filter" 9.3. "Choose color"對話框 9.4. 在Wireshark中使用色彩過濾 9.5. "Enabled Protocols"對話框 9.6. "Decode As" 對話框 9.7. "Decode As: Show" 對話框 9.8. preferences對話框
表格清單 3.1. 導航快捷鍵 3.2. File菜單介紹 3.3. Edit菜單項 3.4. "View"菜單項 3.5. "GO"菜單項 3.6. "Capture"菜單項 3.7. "analyze"菜單項 3.8. 3.9. 3.10. 主工具欄選項 3.11. 4.1. 捕捉文件模式選項 5.1. 特定環(huán)境下的打開文件對話框 5.2. 特定環(huán)境下的"Save Capture File As"對話框 5.3. 不同環(huán)境下的"Merge Capture File As"對話框 6.1. 包列表彈出菜單項 6.2. 包詳情面板彈出上下文菜檔項 6.3. 顯示濾鏡比較操作符 6.4. 顯示過濾的邏輯操作符 7.1. 7.2.
范例清單 2.1. 從源文件編譯 GTK+ 2.2. 編譯、安裝libpcap 2.3. 在RedHat Linux 6.2或者基于該版本得發(fā)行版下安裝需要的RPM包 2.4. 在Deban下安裝Deb 2.5. 4.1. 捕捉來自特定主機的telnet協(xié)議 4.2. 捕捉所有不是來自10.0.0.5的telnet 通信 9.1. Wireshark幫助信息
技術問答
2010-08-03 07:02:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
@Ryan-瑞恩 你好,想跟你請教個問題:
Wireshare如何進行私有協(xié)議定制解碼?應該如何進行 ?
技術問答
2017-03-18 21:05:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
智能輔助問診機器人 - http://robot.kangfuzi.com/?winzoom=1

像爬這個網(wǎng)站,點了一通,一個 網(wǎng)絡連接 都沒看到,怎么實現(xiàn)的,該怎么爬呢?
技術問答
2017-03-03 18:53:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
截獲一個APP和服務器的交互,data沒有解析出來,求大神援助
技術問答
2017-02-15 16:39:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
在使用hosts文件進行ip域名解析的時候,有的時候會碰到一個ip段對應一個域名,想求教hosts文件應該如果寫呢?(不要窮舉法)
多謝
技術問答
2016-12-13 15:12:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
CCProxy 我在 局域網(wǎng)內(nèi) 測試可以,但是 放到 遠程的、非 一個 局域網(wǎng)的 服務器上 不行,因為 這個外網(wǎng)ip 不知道怎么設置,用 ip138 顯示的ip好像不行啊?
這臺電腦 本身有沒有 固定的外網(wǎng)ip呢?

還是說 外網(wǎng) CCProxy 無法實現(xiàn),用其他的呢?
技術問答
2016-10-08 09:57:00
HDC調(diào)試需求開發(fā)(15萬預算),能者速來!>>>
想使用tshark來捕捉查詢sql, 搜索了一下可以這樣使用 如下所示
于是在一個終端中執(zhí)行下面的命令 tshark -i lo0 -Y "mysql.command==3" -T fields -e mysql.query Capturing on 'Loopback' 另一個終端中執(zhí)行下面的操作mysql -h127.0.0.1 -u root -p12345678 select version(); select now(); 但是tshark所在的那個終端無任何輸出。 不知為何我本地無任何輸出?
補充信息 tshark -v TShark (Wireshark) 2.0.4 (v2.0.4-0-gdd7746e from master-2.0) mysql version : 5.7.12


技術問答
2016-07-07 21:37:00