整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          Kubernetes已部署集群切換kube-apiserver等核心容器鏡像倉庫地址

          使用Kubeadm在國內部署Kubernetes集群時,由于無法訪問k8s.gcr.io,就修改了默認的倉庫地址,直接使用了Azure 提供的gcr.azk8s.cn/google_containers倉庫。

          部署信息

          操作系統:Centos7

          Kubernetes:v1.17.0 單Master節點

          問題

          docker pull gcr.azk8s.cn/google_containers/pause:3.1
          Error response from daemon: error parsing HTTP 403 response body: invalid character '<' looking for beginning of value: "<html>\r\n<head><title>403 Forbidden</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>403 Forbidden</h1></center>\r\n<hr><center>nginx/1.14.0 (Ubuntu)</center>\r\n</body>\r\n</html>\r\n"

          近期Azure調整了策略,其倉庫只允許 Azure China IP 使用,不再對外提供服務, 如果確實有需求,可以聯系akscn@microsoft.com并提供IP地址。

          官方說明:https://mirror.azure.cn/help/docker-registry-proxy-cache.html

          這樣我在新增節點時就無法下載`kube-proxy`以及`pause`鏡像了,甚至已有節點出現意外時,對恢復節點也造成一定影響。

          目標

          切換所有相關鏡像至新的倉庫。

          實施

          升級過程中服務會短暫中斷,也可能存在未知風險,應提前做好準備。

          升級過程中服務會短暫中斷,也可能存在未知風險,應提前做好準備。

          升級過程中服務會短暫中斷,也可能存在未知風險,應提前做好準備。

          倉庫切換涉及到兩個核心內容:

          1. Kubernetes集群鏡像,以及現有運行中的所有基礎服務。

          2. Kubeadm配置信息,保證新增節點拿到新的配置信息,進行初始化。

          創建倉庫代理

          創建代理倉庫的細節網上很多,就不詳細贅述。

          網上可以找到很多更好的倉庫,像:阿里、中科大、網易都有相關的服務提供。為了以后不會在出現什么意外,我還是選擇了自建代理,使用了阿里云香港節點的輕量應用服務器做了代理,寬帶峰值30M,每月1T流量,經常會被限速,體驗不怎么好,但好歹不會突然變化了。急需的同學倒是可以拿來應急下。

          • hub.docker.com -> dockerhub.msorg.cn
          • gcr.io -> gcr.msorg.cn
          • k8s.gcr.io -> k8sgcr.msorg.cn
          • quay.io -> quay.msorg.cn

          鏡像清單

          鏡像清單可以通過kubeadm config images list命令查看到。

          k8s.gcr.io/kube-apiserver:v1.17.0
          k8s.gcr.io/kube-controller-manager:v1.17.0
          k8s.gcr.io/kube-scheduler:v1.17.0
          k8s.gcr.io/kube-proxy:v1.17.0
          k8s.gcr.io/pause:3.1
          k8s.gcr.io/etcd:3.4.3-0
          k8s.gcr.io/coredns:1.6.5

          kube-apiserverkube-controller-managerkube-scheduleretcd可以在主節點的/etc/kubernetes/manifests/目錄下找到,yaml配置文件修改保存后立即生效

          corednskube-proxy是發布到Kubernetes集群中的,直接kubectl更新配置。

          pause是與kubelet綁定在一起的,修改service配置即可。

          更新kubeadm配置

          Kubernetes中存有名為kubeadm-configConfigMap配置信息,需要對其進行更新。

          可以使用kubectl edit cm kubeadm-config -n kube-system命令進行編輯,修改imageRepository部分,如:imageRepository: gcr.msorg.cn/google_containers

          更新kube-apiserver

          在主節點的/etc/kubernetes/manifests/目錄中,找到kube-apiserver.yaml文件,修改其中的image部分即可,如:image: gcr.msorg.cn/google_containers/kube-apiserver:v1.17.0

          修改之后保存文件立即生效

          更新kube-controller-manager

          在主節點/etc/kubernetes/manifests/目錄中,找到kube-controller-manager.yaml文件,修改其中的image部分即可,如:image: gcr.msorg.cn/google_containers/kube-controller-manager:v1.17.0

          修改之后保存文件立即生效

          更新kube-scheduler

          在主節點/etc/kubernetes/manifests/目錄中,找到kube-scheduler.yaml文件,修改其中的image部分即可,如:image: gcr.msorg.cn/google_containers/kube-scheduler:v1.17.0

          修改之后保存文件立即生效

          更新etcd

          在主節點/etc/kubernetes/manifests/目錄中,找到etcd.yaml文件,修改其中的image部分即可,如:image: gcr.msorg.cn/google_containers/etcd:3.4.3-0

          修改之后保存文件立即生效

          更新coredns

          coredns被以deployment的方式發布在Kubernetes集群之上,我們只需要修改其配置即可。

          可以使用命令kubectl edit deployment coredns -n kube-system,修改其image部分配置,如:image: gcr.msorg.cn/google_containers/coredns:1.6.5

          更新kube-proxy

          kube-proxy被以daemonset的方式發布在Kubernetes集群之上,我們只需要需改其配置即可。

          可以使用kubectl edit daemonset kube-proxy -n kube-system命令進行編輯,修改其image部分配置,如:image: gcr.msorg.cn/google_containers/kube-proxy:v1.17.0

          更新pause鏡像

          該鏡像配置被放在每個節點上的kubelet啟動命令中,可以通過以下方式確認。

          使用ps -ef | grep kubelet命令查看當前kubelet啟動信息

          root     26588     1  2 Apr11 ?        06:18:01 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --cgroup-driver=systemd --network-plugin=cni --pod-infra-container-image=gcr.msorg.cn/google_containers/pause:3.1

          可以看到在啟動時有pod-infra-container-image參數,修改此參數即可。具體此參數如何修改,因為系統不同,可能方式也不太一樣,下面以Centos7系統為例,Centos7使用了systemd,演示如何查找該參數配置位置。

          第一步:kubeadm已經將kubelet已經被安裝為service了,可以使用service kubelet status查看當前service信息。

          kubelet.service - kubelet: The Kubernetes Node Agent
             Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)
            Drop-In: /usr/lib/systemd/system/kubelet.service.d
                     └─10-kubeadm.conf
             Active: active (running) since Sat 2020-04-11 17:27:03 CST; 1 weeks 1 days ago
               Docs: https://kubernetes.io/docs/
           Main PID: 26588 (kubelet)
              Tasks: 35
             Memory: 196.4M
             CGroup: /system.slice/kubelet.service
                     └─26588 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --cgroup-driver=systemd --network-plugin=cni --pod-infra-...

          從以上信息中我們可以看到當前使用的service配置文件為/usr/lib/systemd/system/kubelet.service,并且加載了10-kubeadm.conf

          第二步:查看service配置

          使用cat /usr/lib/systemd/system/kubelet.service進行查看

          [Unit]
          Description=kubelet: The Kubernetes Node Agent
          Documentation=https://kubernetes.io/docs/
          [Service]
          ExecStart=/usr/bin/kubelet
          Restart=always
          StartLimitInterval=0
          RestartSec=10
          [Install]
          WantedBy=multi-user.target

          發現其中并沒有什么特別的,進一步查看10-kubeadm.conf,至于這個文件呢,在/usr/lib/systemd/system/kubelet.service.d路徑下,或者使用find命令進行查找即可。

          [Service]
          Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
          Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
          # This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
          EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
          # This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
          # the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
          EnvironmentFile=-/etc/sysconfig/kubelet
          ExecStart=
          ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS

          從此文件中我們可以找到/var/lib/kubelet/kubeadm-flags.env文件是在kubeadm initkubeadm join時產生的。基本可以確定下一步的目標了。

          第三步:查看/var/lib/kubelet/kubeadm-flags.env文件

          使用cat /var/lib/kubelet/kubeadm-flags.env查看該文件

          KUBELET_KUBEADM_ARGS="--cgroup-driver=systemd --network-plugin=cni --pod-infra-container-image=gcr.msorg.cn/google_containers/pause:3.1"

          我們會發現需要的內容真的在里面,這時候只需要改了pod-infra-container-image這個參數為我們所需要的,重新啟動kubelet即可,每個node節點都需要手動修改。

          總結

          至此所有操作就已經完成了,當然了,此方式比較野路子。哪位大神有官方相關材料,可以告訴小弟的。

          者:NSS

          翻譯:楊金鴻

          術語校對:韓海疇

          全文校對:林亦霖

          本文約3000字,建議閱讀7分鐘

          本文為帶大家了解R語言以及分段式的步驟教程!

          人們學習R語言時普遍存在缺乏系統學習方法的問題。學習者不知道從哪開始,如何進行,選擇什么學習資源。雖然網絡上有許多不錯的免費學習資源,然而它們多過了頭,反而會讓人挑花了眼。

          為了構建R語言學習方法,我們在Vidhya和DataCamp中選一組綜合資源,幫您從頭學習R語言。這套學習方法對于數據科學或R語言的初學者會很有用;如果讀者是R語言的老用戶,則會由本文了解這門語言的部分最新成果。

          R語言學習方法會幫助您快速、高效學習R語言。

          前言

          在開始學習之前,第一個要回答的問題是:為什么要用R語言?或者R語言為何如此有用?

          R語言是一門快速發展的開源軟件,是SAS、STATA和SPSS這類商業軟件的競爭對手。就業市場對R語言的需求正在迅速上升,微軟等公司也同時承諾將致力讓R語言成為數據科學通用語言。

          看看由Revolution Analytics制作的90秒視頻(https://www.youtube.com/watch?v=VlJnNSeO1uQ),您就知道R語言的用處。順便說下,微軟剛剛收購了Revolution Analytics。

          步驟一:配置計算機環境

          建立R語言學習環境最簡單方法是通過綜合R語言歸檔網絡(CRAN)下載(https://cran.r-project.org/)到您的本地計算機上。可以選擇Linux、Mac和Windows對應二進制文件下載。

          您可能會考慮使用R語言自帶的控制臺,但我們建議您安裝R語言集成開發環境(IDE)。RStudio(https://www.rstudio.com/)是最有名的IDE,它能讓R語言編碼更容易、更快,還能讓您輸入多行代碼、處理圖形、安裝和維護程序,有效引導您的編程環境。RStudio此外可以選用基于eclipse的Architect(http://www.openanalytics.eu/architect)。如果需要安裝圖形用戶界面(GUI),請選擇R-commander(http://www.rcommander.com/)或Deducer(http://www.deducer.org/pmwiki/index.php?n=Main.WindowsInstallation)。

          課后作業

          • 安裝R和RStudio。

          • 安裝Rcmdr、rattle和Deducer程序包。以及推薦或依賴的程序包,包括GUI。

          • 使用庫命令加載安裝程序,并打開GUI。

          步驟二:R語言基礎學習

          您應該首先了解語言、庫和數據結構基礎知識。

          如果您更傾向于在線交流方式學習R語法,DataCamp(https://www.datacamp.com/courses/free-introduction-to-r)提供的免費在線R教程是很好的資源。還可以選擇后續課程:中級R編程(https://www.datacamp.com/courses/intermediate-r)。另一種學習方法是在線版本swirl(https://www.datacamp.com/swirl-r-tutorial),它能讓您在類似RStudio環境中學習R語言。

          在互動學習環境中,您可以選擇參加Coursera(https://www.coursera.org/specializations/jhu-data-science)或Edx(https://www.edx.org/course/introduction-r-programming-microsoft-dat204x-0)上mooc課程。

          除了上述在線資源,您還可以考慮以下優秀資源:

          • CRAN免費教學R語言(https://cran.r-project.org/doc/manuals/R-intro.pdf)。

          • Jared Lander’s R for Everyone(http://www.jaredlander.com/r-for-everyone/)

          • Quick-R(http://statmethods.net/)

          專門學習:閱讀、數據幀、表、概述、描述、加載和安裝包、使用繪圖命令可視化數據。

          課后作業

          • 使用DataCamp免費在線R教程,熟悉基本的R語法。

          • 創建Github(http://github.com/)賬號。

          • 通過google幫助,解決安裝過程中出現的問題。

          • 安裝swirl包并學習R編程(見上文)。

          步驟三:了解R社

          強大社區的存在是R語言發展迅速、大獲成功的主要原因。社區中核心的是R語言的“包”生態系統。R語言程序包可以在CRAN、bioconductor、github和bitbucket中下載。在Rdocumentation(http://www.rdocumentation.org/)中,您可以輕松搜索來自CRAN、github和bioconductor中能滿足您當前工作需要的程序包。與在R語言程序包生態系統同樣重要的是,您可以在R endeavours上輕松獲得幫助與反饋。首先,R內置幫助系統,您可以通過命令來訪問。同時,在Analytics Vidhya Discussions,Stack OverflowR語言是增長最快語言。R-bloggers(http://www.r-bloggers.com/)匯集許多R語言愛好者寫的博文。

          課后作業:

          • 訪問CranTask Views了解R語言生態系統。

          • 在http://r-bloggers.com上注冊并訂閱每日新聞。

          步驟四:數據導入和操作

          導入和操作數據是數據科學工作流程中重要步驟。R語言允許使用特定包導入不同數據格式,從而使您工作更輕松,如下:

          • readr:導入平面文件。

          • Readxl package:將excel文件轉化為R語言。

          • haven package包:讓您將SAS、STATA和SPSS數據文件導入R語言。

          • Databases:連接通過像RMySQL和RpostgreSQL包,使用DBI訪問和操作。

          • rvest: 網頁數據抓取。

          一旦數據在工作環境中可用,您就可以使用下面程序包操作:

          • 整理數據的tidyr程序包。

          • stringr包處理字符串操作。

          • 對象數據幀,可以學習dplyr包輸入和輸出(https://www.datacamp.com/courses/dplyr-data-manipulation)。

          • 需要執行繁重數據爭用任務?試試data.table程序包。

          • 執行時間序列分析?嘗試一下像zoo,xts和quantmod程序包。

          課后作業

          • 通過“導入數據進入R語言”課程,或閱讀文章1、2、3、4。掌握導入數據軟件包。

          • 通過RStudio觀看Data Wrangling with R 。(https://www.rstudio.com/resources/webinars/data-wrangling-with-r-and-rstudio/)

          • 閱讀并練習如何使用dplyr、tidyr和data.table程序包。

          步驟五:有效數據可視化

          自己創建數據可視化作品是一件很自豪的事情。然而,數據可視化既是一項技能,也是一門藝術。許多學者閱讀Edward Tufte 的“可視化定量數據”原理,或者StephenFew的 “pitfalls on dashboard design”。也可以閱讀NathanYau在FlowingData 寫的博文,來獲得創建R語言可視化靈感。

          1. 平面圖無處不在

          R語言提供了多種創建圖形方法,使用原理圖創建圖形是標準的方法。然而,有一些好的工具(或包)使用更簡單的方式來創建,查看圖形。

          • 在R語言中學習基本圖形語法是數據可視化中一種實用方法。

          • 在R語言中ggplot是數據可視化中最重要的包,并且很受歡迎,網上有很多它的學習資源,比如在線ggplot2教程,cheatsheet ,和以及一本由哈德利韋翰編寫的教學書。

          • ggvis程序包允許您使用基本圖形語法創建交互式web圖形(參見教程)。

          • 您知道Hans Rosling ted課程嗎?教您如何的用googleVis(一個帶有谷歌圖表接口)來重建圖表。

          • 如果您遇到了繪制數據的問題,這篇文章會對您有所幫助。在這個CRAN任務視圖中可以查看到更多的可視化資源。或者查看R語言數據可視化指南。

          2. 地圖無處不在

          您對分析空間可視化數據感興趣嗎?學習本教程:介紹R語言空間數據,您會輕松地使用這些包。

          • 源自Google maps和ggmap開放街道的靜態圖片,可用來創建可視化空間數據和模型。

          • Ari Lamstein’s中的choroplethr程序包。

          • tmap 程序包

          3. HTML插件

          HTML插件是R語言可視化產品中非常有前景的插件,您可以用簡單的方式創建交互式web可視化(參見RStudio教程),掌握這種可視化方法將會成為R語言學習中必備技能。其帶來的視覺效果會給您朋友和同事留下深刻印象。

          • leaflet創建動態圖片。

          • 使用dygraphs生成時間序列數據圖表。

          • 互動表(datatable)。

          • DiagrammeR創建圖和流程圖。

          • MetricsGraphics創建散點圖、線圖和直方圖。

          課后作業

          • 理解基本圖形語法原理。

          • 學習ggplot2教程。

          • 使用RStudio環境學習html插件。

          步驟六:數據挖掘、機器學習

          對于新的統計數據學習方法,我們推薦下列資源:

          • Andrew Conway’s課程:R語言統計數據簡介。

          • 杜克大學數據分析和統計推斷。

          • R語言實用數據科學。

          • 約翰霍普金斯大學數據科學專業課程。

          • R語言數據科學使用指南。

          如果您想提高機器學習能力,可以考慮從以下教程開始學習:

          • 機器學習算法要點。

          • 自行車共享大賽--一套R語言完整解決方案。

          • Kaggle上的機器學習課程。

          • 掌握機器學習。

          • 介紹機器學習。

          確保在相關的CRAN任務視圖中查看到R語言可用的機器學習資源。

          課后作業

          • 從統計學課程開始入門。

          • 學習Kaggle上免費機器學習課程。

          • 看Rattle中的一些R語言數據挖掘書。

          • 可以從這本小冊子上學習時間序列——A Little Book for Time Series in R .

          步驟七:報告結果

          與數據科學愛好者交流成果,分享見解是一件很重要的事情。幸運的是,R語言針對這個問題有一些非常實用工具。

          第一個工具是R Markdown,采用knitr和pandoc復制方式生成您的數據分析結果報告。使用R markdown工具,R語言最終生成文檔,替換R語言代碼。文檔可以是html、word、pfd、ioslides等格式。您可以通過本教程學到更多知識并使用cheatsheet作為參考資料。

          第二個工具是ReporteRs,它是個創建Microsoft(Worddocx和Powerpoint pptx)和html R語言文檔程序包,并可以在Windows、Linux、Unix和Mac OS系統上運行。像R Markdown工具一樣自動生成R語言報告,點擊這里我們來看看如何操作。

          第三個是Shiny,目前R語言中最令人興奮的工具。使R語言構建交互式web應用程序變得非常容易。您可以把分析報告轉換為交互式web應用程序,您不需要了解HTML、CSS或Javascript相關知識。如果您想要學習Shiny ,請點擊RStudio learning portal。

          課后作業

          • 使用RMarkdown或ReporteRs創建第一個交互式報告。

          • 嘗試構建一個Shiny應用。

          練習

          只有通過大量練習才能成為優秀R語言程序員。因此,要定期解決數據科學中的問題。我們的建議是趕緊開始與Kaggle上的數據科學家交流。

          在解決問題中測試自己的R語言水平--練習中的問題。

          步驟八:時間序列分析

          R語言有一個用于專屬任務視圖時間序列。如果你想在R語言中做一些時間序列分析,這將是您開始的地方。您很快會發現工具的強大。

          想要從在線資源中掌握時間序列分析是件不容易的事情。好的切入點是一本關于時間序列的書或者選擇《原理與實踐》這本書。在程序包方面,您需要熟悉Zoo與xts程序包。Zoo為您提供了常用的保存時間序列對象格式,而xts供了操作時間序列的數據集工具。

          輔助資源: 時間序列綜合教程。

          課后作業

          • 選擇上述列出的時間系列教程,開始您的分析。

          • 使用quantmod或quandl程序軟件包下載財務數據,開始您的時間序列分析。

          • 使用諸如dygraphs的程序包創建您的可視化時間序列數據和分析。

          文本挖掘一個重要工具

          學習文本挖掘,您可以從edge課程中學習。雖然課程已經結束,但是您仍然可以訪問這些課程。

          練習

          • 文本挖掘競賽--一套R語言的完整解決方案。

          步驟九:成為R語言大師

          現在您已經掌握了大部分R語言數據分析,是時候給出一些高級課程資源了。您很可能已經知道其中的一些內容,但不妨看看這些教程。

          • Hadley Wickham的高級R語言教程。

          • 在Hadoop、MongoDB或NoSQL中使用R語言。

          • 微軟的RevoScaleR 程序包

          原文鏈接:

          https://www.analyticsvidhya.com/learning-paths-data-science-business-analytics-business-intelligence-big-data/learning-path-r-data-science/

          楊金鴻,北京護航科技有限公司員工,在業余時間喜歡翻譯一些技術文檔。喜歡閱讀有關數據挖掘、數據庫之類的書,學習java語言編程等,希望能在數據派平臺上熟識更多愛好相同的伙伴,今后能在數據科學的道路上走的更遠,飛的更遠。

          在,我們已經充分了解了 HTTP 和 Socket 的關系,也了解了 HTTP 報文的格式,為了讓小伙伴能夠加深對這兩個概念的理解,本文我們來看看如何利用 Socket 模擬 HTTP 請求。如果小伙伴們對 HTTP 和 Socket 的關系、HTTP 報文格式尚不熟悉的話,可以參考前面的文章 Http 和 Socket 到底是哪門子親戚?。

          由于 HTTP 是基于 TCP 協議的應用層協議,因此我們可以用更為底層的方式來訪問 HTTP 服務,即直接使用 Socket 完成 HTTP 的請求和響應。我們前面說過,HTTP 的任務就是完成數據的包裝, Socket 提供了網絡的傳輸能力,所以我們只需要按照 HTTP 報文的格式來組裝數據,然后利用 Socket 將數據發送出去,就能得到回應。

          POST 請求上傳數據

          假設我現在有一個數據接口 http://localhost/hello,該接口每次接收一個參數 name ,調用成功之后返回給用戶一個 hello:name 字符串,那我們用 Socket 來實現這樣一個 HTTP 請求。

          首先,我們要先組裝出 HTTP 的請求頭,如下(如果小伙伴對下面這個請求頭有疑問,請復習 Http 和 Socket 到底是哪門子親戚?一文):

          POST /hello HTTP/1.1
          Accept:text/html
          Accept-Language:zh-cn
          Host:localhost
          
          name=張三
          

          我這里為了簡單,只添加了三個請求頭,然后我們通過 Socket 將上面這個字符串發送出去:

          Socket socket = new Socket(InetAddress.getByName("localhost"), 80);
          OutputStream os = socket.getOutputStream();
          String data = "name=張三";
          int dataLen = data.getBytes().length;
          String contentType = "Content-Length:" + dataLen+"\r\n";
          os.write("POST /hello HTTP/1.1\r\n".getBytes());
          os.write("Accept:text/html\r\n".getBytes());
          os.write("Accept-Language:zh-cn\r\n".getBytes());
          os.write(contentType.getBytes());
          os.write("Host:localhost\r\n".getBytes());
          os.write("\r\n".getBytes());
          os.write(data.getBytes());
          os.write("\r\n".getBytes());
          os.flush();
          

          我在 Serlvet 中接收這個請求并作簡單處理,如下:

          BufferedReader br = new BufferedReader(new InputStreamReader(req.getInputStream(),"UTF-8"));
          StringBuffer sb = new StringBuffer();
          String str;
          while ((str = br.readLine()) != null) {
              sb.append(str).append("\r\n");
          }
          System.out.println("sb:"+sb.toString());
          resp.setContentType("text/html;charset=utf-8");
          PrintWriter out = resp.getWriter();
          out.write(sb.toString());
          out.flush();
          out.close();
          

          然后通過 Socket 中的輸入流我就能拿到響應結果,如下:

          BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
          StringBuffer sb = new StringBuffer();
          String str;
          while ((str = br.readLine()) != null) {
              sb.append(str).append("\r\n");
          }
          System.out.println(sb.toString());
          

          響應結果如下:

          HTTP/1.1 200 
          Content-Type: text/html;charset=utf-8
          Transfer-Encoding: chunked
          Date: Sun, 03 Dec 2017 10:46:52 GMT
          
          name=張三
          

          這是一個簡單的通過 POST 請求下載文本的案例。接下來我們再來一個 GET 請求下載圖片的案例,來加深對 Socket 的理解。

          GET 請求下載圖片

          這個實際上也不難,但是要實現圖片的下載需要我們首先熟悉HTTP響應的數據格式,不熟悉的小伙伴可以閱讀 Http 和 Socket 到底是哪門子親戚?一文。  

          下載圖片,響應頭是文本文件,響應數據是二進制文件,我們要想辦法通過空行將這兩塊數據分開,分別處理。為了解決這個問題,我首先提供一個工具類,這個工具類用來實現一行一行的解析字節流,如下:  

          public class BufferedLineInputStream {
              private InputStream is;
          
              public BufferedLineInputStream(InputStream is) {
                  this.is = is;
              }
          
              /**
               * @param buf    將數據讀入到byte數組中
               * @param offset 數組偏移量
               * @param len    數組長度
               * @return 返回值表示讀取到的數據長度 -1表示數據讀取完畢,0表示其他異常情況
               */
              public int readLine(byte[] buf, int offset, int len) throws IOException {
                  if (len < 1) {
                      return 0;
                  }
                  //count用來統計已經向數組中存儲了多少數據
                  int count = 0, c;
                  while ((c = is.read()) != -1) {
                      buf[offset++] = (byte) c;
                      count++;
                      //如果一行已經讀完或者數組已滿
                      if (c == '\n' || count == len) {
                          break;
                      }
                  }
                  return count > 0 ? count : -1;
              }
          }
          

          然后將響應中的頭信息和圖片分別保存在不同的文件中,數據解析的核心思路就是一行一行讀取響應數據,當遇到 \r\n 表示頭信息已經讀取完了,要開始讀取二進制數據了,二進制數據讀取到之后,將之保存成圖片即可。核心代碼如下:

          fos = new FileOutputStream("E:\333.png");
          pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("E:\222.txt")));
          socket = new Socket(InetAddress.getByName("localhost"), 80);
          OutputStream out = socket.getOutputStream();
          out.write("GET /1.png HTTP/1.1\r\n".getBytes());
          out.write("Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n".getBytes());
          out.write("Accept-Language:zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3\r\n".getBytes());
          out.write("Host:localhost\r\n".getBytes());
          out.write("\r\n".getBytes());
          
          BufferedLineInputStream blis = new BufferedLineInputStream(socket.getInputStream());
          int len;
          byte[] buf = new byte[1024];
          while ((len = blis.readLine(buf, 0, buf.length)) != -1) {
              String s = new String(buf, 0, len);
              System.out.println(s);
              if (s.equals("\r\n")) {//表示頭信息讀取完畢
                  break;
              }
          }
          //開始解析二進制的圖片數據
          while ((len = blis.readLine(buf, 0, buf.length)) != -1) {
              fos.write(buf, 0, len);
          }
          

          OK,Socket 模擬 HTTP 請求我們就先說到這里,兩個案例,希望能夠加深小伙伴對 Socket 和 HTTP 的理解。


          主站蜘蛛池模板: 波多野结衣免费一区视频| 果冻传媒一区二区天美传媒| 一区二区精品在线| 国产精品视频一区二区猎奇| 在线不卡一区二区三区日韩| 日韩免费观看一区| 丰满人妻一区二区三区视频 | 国产在线观看一区二区三区四区 | 国产SUV精品一区二区四| 激情综合一区二区三区| 国产丝袜一区二区三区在线观看| 一区二区三区观看免费中文视频在线播放| 春暖花开亚洲性无区一区二区| 久久青草国产精品一区| 亚洲国产精品一区二区三区久久| 国产成人综合亚洲一区| 一本AV高清一区二区三区| 精品一区二区三区四区在线播放| 天天综合色一区二区三区| 中文字幕日韩丝袜一区| 久久蜜桃精品一区二区三区| 久久er99热精品一区二区| 久久精品一区二区三区不卡| 中文字幕久久久久一区| 国产一区二区三区内射高清| 国产一区二区三区小向美奈子| 国产精品盗摄一区二区在线| 亚洲AV成人精品日韩一区| 亚洲AV无码一区二三区| 在线精品国产一区二区三区| 一区二区三区免费精品视频| 日本韩国一区二区三区| 日本一区二区三区在线看| 免费高清av一区二区三区| 亚洲熟妇av一区| 精品伦精品一区二区三区视频| 无码国产精品一区二区免费虚拟VR| 日本一区二区在线| 一区免费在线观看| 中文字幕一区二区三| av无码人妻一区二区三区牛牛|