『壹』 iOS客戶端與伺服器的數據交互總結
前言:
本文總結了iOS客戶端與伺服器進行交互時,採用 RESTful API + Json 的交互方式,針對不 同的數據形式以及不同的解析方法,如有不足之處,歡迎指正。
先了解一下相關的基本概念。
HTTP通信:
即使用HTTP協議進行通信,工作原理是客戶端向伺服器端發送一條HTTP請求,伺服器收到之後先 解析客戶端的請求,之後會返回數據給客戶端,然後客戶端再對這些數據進行解析和處理。HTTP 連接採取的是「請求—響應」方式,即在請求時建立連接通道,當客戶端像伺服器端發送請求時,服 務器端才能向客戶端發送數據。
Socket通信:Socket又稱套接字,在程序內部提供了與外界通信的埠,即埠通信。通過建立 socket連接,可為通信雙方的數據傳輸傳提供通道。Socket的主要特點有數據丟失率低,使用簡 單且易於移植。Socket類似於peer to peer的連接,一方可隨時向另一方喊話。
小結:HTTP和Socket都是基於TCP協議的。使用兩種通信方式的情況是: 使用HTTP的情況:雙方不需要時刻保持連接在線,比如客戶端資源的獲取、文件上傳等。
使用UDP的情況:大部分即時通訊應用(QQ、微信)、聊天室、蘋果APNs等。
主要有四種:
數據流
1.從web伺服器響應到手機終端的數據 一般打包在一個位元組數組中,這個位元組數據中包含了不同的 數據類型,客端端採取java數據流和過慮流的方式從位元組數組中取出各種類型的數據。
這種交互方式我在學習iOS之初用過,實際項目中並沒有發現哪家公司在用。這種方式了擴展 了iOS平台在訪問Web伺服器進行交互時的解析數據能力,僅供研究學習。
2.XML Webservice的標准數據格式。 Protocol Buffers
3.Protocol Buffers 是一種輕便高效的結構化數據存儲格式,支持跨平台。它很適合做數據存儲或 RPC 數據交換格式。比 JSON 最大的優點就是傳輸的時候數據體積可以壓縮很小,傳輸效率比較 高。本人在這個在項目中沒有用到過。
4.JSON
JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。 易於人閱讀和編寫。同時也易於機器解析和生成。毫無疑問,大家最常用。
本文重點會介紹關於Json數據格式 的常用格式。
Json數據格式 的採用,根據業務情況,一般是團隊中的共識。技術的迭代更新,到後期基本都會考慮多 個平台的通用性、可移植性和可讀性。比如 我們開發團隊,有移動端開發(Android、iOS)、前端開發 (H5開發)和後台開發(golang開發)。
關於伺服器的開發規范,我們先來了解一下。
伺服器開發規范 我們採用的是 RESTful , RESTful 是目前最流流行的 API設計規范,用於web數據接
口的設計。
• 面面向資源(URI),具有解釋性;
• 行為(GET / POST / PUT / PATCH / DELETE)與資源(URI)分離,更更加輕量量;
• 數據描述簡單,使用用JSON、XML、Protocol Buffers即可全覆蓋, 主要使用用JSON;
它的核心原則是定義用少量方法就能操作的命名資源。資源和方法可視為API的 和動詞。
• GET :讀取(Read)
• POST :新建(Create)
• PUT :更新(Update),通常是全部更更新
• PATCH :更新(Update),通常是部分更更新
• DELETE :刪除(Delete)
項目搭建之始,客戶端和伺服器一般用 Get 和Post的方式來交互,隨著業務的演進和技術的規范迭代, 到後期我們都得按規范來。於是 我們採用了上述幾種方式來設計伺服器介面,相應地,移動端的請求方 式也得與之對應。
至此,不在贅述 RESTful API 的設計規范,可自行網路了解更多。
介面的數據一般都採用JSON格式進行傳輸,不過,需要注意的是,JSON的值只有六種數據類型:
•Number:整數或浮點數
•String:字元串
•Boolean:true 或 false
•Array:數組包含在方括弧 [] 中
•Object:對象包含在大括弧 {} 中
•Null:空類型
傳輸的數據類型不能超過這六種數據類型,不能用Date數據類型,不同的解析庫解析方式不同,可能會 導致異常,如果遇到日期的數據,最好的方式就是使用毫秒數表示日期。
本文總結了iOS與伺服器的交互方式和數據類型,並總結了在實際項目的簡單運用。數據格式的運
用場景遠不止上面提到的幾種場景,後期會持續完善,如有不足之處,歡迎指出。
『貳』 web後台伺服器是如何工作的
近期准備session,希望能跟大家輕松地分享一些東西,一些常見的場景。比如:web後台伺服器到底是如何工作的。
上網過程對於普通人:首先,他需要一台電腦,然後,他的電腦可以接入網路,最後,他可以打開瀏覽器鍵入自己想要瀏覽的網址,然後就可以上網了。但是對於計算機來講,是一個比較復雜的過程,裡麵包含了信息如何保存,信息如何傳遞以及信息如何展示的過程。所以,針對整個上網過程,我們從前到後,分析一下其中包含的各種技術細節,可能不全,目的是拋磚引玉,希望大家在簡單的流程當中學習更多的東西分享出來,一些基礎知識則當做復習。之前buddy王老吉講過瀏覽器的工作方式,所以本文內容不包含瀏覽器的工作方式,重點在於各種後台服務以及通信層面的分析。
前面說到,用戶瀏覽器中鍵入網址便瀏覽網頁信息,這個網址實際上就是URL,英文全稱是Uniform Resource Locator——統一資源定位符。
完整的、帶有授權部分的普通統一資源標志符語法看上去如下:
協議://用戶名:密碼@子域名.域名.頂級域名:埠號/目錄/文件名.文件後綴?參數=值
協議部分可以是http,https,ftp等協議類型。
前面提到,互聯網上的每個文件都有一個唯一的URL,那麼,到底是如何確認的。前面提到了協議,協議是什麼?比如大家寫信時都需要寫郵編、地址和姓名,便可以通過這種方式將信郵寄到世界上唯一的那個人手裡,填寫的郵編,地址和姓名就是一種協議。協議的價值在於世界上所有的瀏覽器和後台伺服器都需要遵循http這些協議,才能正常進行信息的傳遞。
計算機通信跟人的通信是類似的,也是遵循各種協議的,不同的協議承載著不同的功能。通常,瀏覽器上網使用的是http或者https協議,從網路分層的角度來講,這些協議屬於應用層協議,建立在傳輸層之上。傳輸層跑是什麼協議呢?相信大家都非常熟悉,傳輸層跑的是TCP和UDP協議,再往下就是網路層,網路層上面跑的是IP數據報。每層的功能各不相同,每層的協議也不同,但是一般來講,越往下層,協議會越少,這樣才能化繁為簡,從而支持不同的上層協議。傳輸層協議一般是由操作系統層面支持的,同時還需要跟網路層進行交互(對於物理機來說就是網卡),所以針對我們操作系統之上的程序員來講,新創造的協議都是應用層協議,因為我們的通信都是在傳輸層(TCP和UDP)基礎之上構建的。
http是應用層協議,也就是說,在界面敲下網址那一刻,實際上瀏覽器向伺服器發送了http協議格式的消息,也叫做http請求。http協議是構建在tcp協議之上的,而tcp是可靠的協議,所以http協議無需考慮可靠性,只管傳輸就可以了。
http協議比較簡單,如下所示:
那麼瀏覽器又是如何組織http請求,並且將信息發送的相應伺服器的呢?例如: http://www..com
我們鍵入的僅僅是伺服器域名,但是實際上在網路中我們通信是通過套接字來進行通信的。套接字=IP + 埠,在網路中,IP的作用是用來在網路層進行路由定址,尋找唯一的主機;埠的作用是用來在這個主機中尋找唯一的進程。總體來說,套接字可以用來在網路中確定唯一主機的唯一進程,所以通過套接字我們可以進行通信。
但是問題是上網通過域名來訪問,那麼是如何通過域名來確認唯一主機的唯一後台web伺服器進程的呢?做一個假設,如果我們可以在互聯中提供一個確定的服務,這個服務裡面裝有域名到套接字的映射,上網的人通過這個服務獲取對應域名的套接字,那麼這個問題不就解決了。而實際上,DNS服務原理簡單來說就是剛才假設的方法,服務商通過提供公共的DNS服務,大家上網時便可以查詢到相應域名對應的套接字,通過這個套接字便可以訪問確定的伺服器了。真正的DNS服務其實更為復雜,分為迭代式查詢和遞歸式查詢,兩種方式各有優劣,同時,為了性能,DNS服務通常也配有不同級別的緩存,關於DNS的具體實現有興趣的可以自行查詢資料學習。
總結一下,上網時瀏覽器實際上做了兩件事,第一,通過瀏覽器內置的DNS客戶端,向DNS伺服器發送請求,獲取域名對應套接字;第二,使用套接字發送http請求,獲取數據,然後在瀏覽器端呈現。
另外,DNS服務也需要遵循某種協議才能通信,其協議為DNS協議,其服務固定為53埠,屬於應用層協議。DNS英文為DomainNameSystem。其實DNS服務跟電話簿的工作方式一樣,因為你沒法記得每個人的電話號碼,但是很容易記住每個人的名字。
上網前,我們的計算機裡面什麼都沒有,為何鍵入網址後能在界面顯示出各種各樣的數據?實際上,數據都來自於後台伺服器,所有的數據當然也都存儲在後台伺服器,瀏覽器僅僅請求數據。前面講了,請求數據時,使用套接字加上http請求來獲取數據,後台則必定要提供相應的套接字,接收信息,解析http請求,才能正常的返回客戶端需要的數據。所以,後台伺服器做的工作,第一,綁定套接字,通過該套接字向外提供http服務;第二,解析http請求,根據請求返回響應。
理論上講,我們可以實現自己的http服務,並且解析不同的http請求,返回響應。但是,作為開發者來講,重復造輪子是不推薦的,市面上有多種現成框架供我們選擇。對於java開發者來講,就有tomcat或者jetty,其他語言理論上也有類似的框架。tomcat和jetty幫我們做了什麼呢?實際上最主要的功能還就是接受http請求,針對不同的請求返回響應,當然,他們也提供了更多的高級特性,比如遵循servlet規范,使人們更高效的開發web應用。
總結一下,上網的實際流程在程序員的角度來看,首先需要通過DNS服務解析域名,獲取該域名所在web伺服器應用程序的套接字,然後瀏覽器組裝符合http協議的請求,通過套接字發送給web伺服器,web伺服器解析請求,根據解析結果將需要返回的內容組裝符合http協議的響應,瀏覽器接到響應後,根據http協議解析響應,獲取數據,將數據展示在瀏覽器上。
包含的知識點:DNS協議,HTTP協議,計算機網路知識,後台伺服器實現(tomcat/jetty等)。
『叄』 C++ 如何使用 Socket 類向 HTTP 伺服器發送數據和接收響應
客戶端發送請求給伺服器,伺服器處理完畢以後把Socket tempSocket = (你還可以檢測收到的1W8數據是3W8裡面的哪一部分. 這個把發送的數據和接收的
『肆』 Ajax向伺服器發送請求和接收返回的信息
Ajax向伺服器發送請求
Ajax對象創建完成後,下面就要講解一下Ajax如何使用。首先詳細講解一下Ajax向伺服器發送請求所需的兩個方法,具體如下:
(1)open()方法
open()方法用於創建一個新的HTTP請求,並指定此請求的類型(如GET、POST等)、URL以及驗證信息,其聲明方式如下所示:
在上述聲明中,method用於指定請求的類型,其值可為POST、GET、PUT及PROPFIND,大小寫不敏感;URL表示請求的地址,可以為絕對地址也可以為相對地址,並且可以傳遞查詢字元串。其餘參數為可選參數,其中,asyncFlagy用於指定請求方式,同步請求為false,默認為非同步請求true;userName用於指定用戶名,password用於指定密碼。
(2)send()方法
send()方法用於發送請求到HTTP伺服器並接收回應。其聲明方式如下所示:
在上述聲明中,content用於指定要發送的數據,其值可為DOM對象的實例、輸入流或字元串,一般與POST請求類型配合使用,需要注意的是,如果請求聲明為同步,該方法將會等待請求完成或者超時才會返回,否則此方法將立即返回。
需要注意的是,在使用GET方式傳遞特殊字元或中文參數時,要使用JavaScript中的encodeURIComponent()函數將其轉換成「%十六進制數」的形式,防止在某些瀏覽器(如IE瀏覽器)中中文亂碼的問題。
Ajax接收伺服器返回的信息
了解Ajax向伺服器發送請求後,下面將對Ajax如何接收伺服器返回的信息(例如,HTML標簽、CSS樣式、字元串、XML、JSON等),進行詳細講解。具體如下:
(1)readyState屬性
readyState屬性用於返回Ajax的當前狀態,狀態值有5種形式,具體如表所示。
(2)onreadystatechange屬性
onreadystatechange事件屬性用於感知readyState屬性狀態的改變。為了大家更好的理解這兩個屬性的使用,下面創建一個伺服器端的文件index.php,用於輸出字元串,然後在瀏覽器端index.html中向伺服器端發送請求,並在控制台輸出狀態值。具體示例如下所示:
創建伺服器端文件:index.php
創建瀏覽器端文件:index.html
在瀏覽器中訪問客戶端文件,按「F12」鍵,切換到控制台,查看輸出結果,具體如下圖所示。
從圖中可以看出,通過onreadystatechange事件屬性可以清晰的感知Ajax狀態的改變,同時使用readyState獲取轉變後的狀態值。例如Ajax從0(未初始化)狀態變成1(初始化)狀態值時,Ajax此時的狀態值為1。
(3)status屬性
status屬性用於返回當前請求的HTTP狀態碼,常見的狀態碼如表所示。
值得一提的是,在感知當前Ajax對象狀態時,為了追求程序的嚴謹性,需要同時判斷當前HTTP狀態status是否等於200(請求成功)。
需要注意的是,Ajax中的statusText屬性,僅當數據發送並接收完畢後,才可以獲取當前請求的響應狀態。
(4)獲取響應信息的相關屬性
當數據接收完畢且請求伺服器的請求成功時,即可以使用Ajax中提供的相關屬性獲取伺服器的響應信息。具體的屬性及相關說明如下表所示。
在上表中,responseText屬性用於返迴文本格式的響應數據;屬性responseBody表示直接從伺服器返回並未經解碼的二進制數據;responseXML屬性用於接收XML數據格式的響應數據。
『伍』 伺服器如何接收GPS定位器發送過來的數據
架設伺服器平台,很簡單;這里介紹一個 GPSBD衛星定位監控系統Simple版本的定位系統
他們系統是JAVA開發,首先伺服器需要搭建JAVA環境,Mysql資料庫,以及Reids緩存服務;
然後啟動程序文件,一步一步操作即可;經過測試系統基本上市面上的各類GPS北斗定位設備都是支持的
在自己伺服器搭建好GPS平台以後,就可以將設備的IP 埠配置到自己伺服器對應的IP埠上,這樣設備數據就會發往伺服器,然後通過這套GPS定位系統就可以查看位置了
『陸』 java socket編程,客戶端發送文件給伺服器,伺服器接收到文件後如何返回確認信息告訴客戶端文件已接收
importjava.io.BufferedReader;
importjava.io.File;
importjava.io.FileNotFoundException;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.InputStreamReader;
importjava.net.ServerSocket;
importjava.net.Socket;
/**
*
*文件名:ServerReceive.java
*實現功能:作為伺服器接收客戶端發送的文件
*
*具體實現過程:
*1、建立SocketServer,等待客戶端的連接
*2、當有客戶端連接的時候,按照雙方的約定,這時要讀取一行數據
*其中保存客戶端要發送的文件名和文件大小信息
*3、根據文件名在本地創建文件,並建立好流通信
*4、循環接收數據包,將數據包寫入文件
*5、當接收數據的長度等於提前文件發過來的文件長度,即表示文件接收完畢,關閉文件
*6、文件接收工作結束
*簡大
*
*【註:此代碼僅為演示客戶端與伺服器傳送文件使用,
*每一個數據包之前沒有文件協議命令
*具體的協議傳輸和文件傳出的使用階段可根據自己程序自行放置】
*
*
*作者:小菜鳥
*創建時間檔氏:2014-08-19
*
行咐散**/
publicclassServerReceive{
publicstaticvoidmain(String[]args){
/**與伺服器建立連接的通信句柄*/
ServerSocketss=null;
Sockets=null;
/**定義用於在接收後在本地創建的文件對象和文件輸出流對象*/
Filefile=null;
FileOutputStreamfos=null;
/**定義輸入流,使用socket的inputStream對數據包進行輸入*/
InputStreamis=null;
/**定義byte數組來作為數據包的存儲數據包*/
byte[]buffer=newbyte[4096*5];
/**用來接收文件發送請求的字元串*/
Stringcomm=null;
/**建立socekt通信,等待伺服器進行連接*/
try{
ss=newServerSocket(4004);
s=ss.accept();
}catch(IOExceptione){
e.printStackTrace();
}
/**讀取一行客戶端發送過來的約定信息*/
try{
InputStreamReaderisr=newInputStreamReader(s.getInputStream());
BufferedReaderbr=newBufferedReader(isr);
comm=br.readLine();
}catch(IOExceptione){
System.out.println("伺服器與客戶端斷開連接");
}
/**開始解析客戶端發送過來的請求命令*/
intindex=comm.indexOf("/#");
/**判斷協議是否為發送文件的協議*/
Stringxieyi=comm.substring(0,index);
if(!xieyi.equals("111")){
System.out.println("伺服器收到的協議碼不正確");
return;
}
/**解析出文件的名字和大小*/
comm=comm.substring(index+2);
index=comm.indexOf("/#");
Stringfilename=comm.substring(0,index).trim();
Stringfilesize=comm.substring(index+2).trim();
/**創建空文件,用來進行接收文件*/
file=newFile(filename);
if(!file.exists()){
try{
file.createNewFile();
}catch(IOExceptione){
System.out.println("伺服器端創建文件失敗");
}
}else{
/**在此也可以詢問是否覆蓋*/
System.out.println("本路徑已存在相同文件,進行覆蓋");
}
/**【以上就是客戶端代碼中寫到的伺服器的准備部分】*/
/**
*伺服器接收文件的關鍵代碼*/
try{
/**將文件包裝到文件輸出流對象中*/
fos=newFileOutputStream(file);
longfile_size=Long.parseLong(filesize);
is=s.getInputStream();
/**size為每次接收數據包的長度*/
intsize=0;
/**count用來記錄已接收到文件的長度*/
longcount=0;
/**使用while循環接收數據包*/
while(count<file_size){
/**從輸入流中讀取一個數據包*/
size=is.read(buffer);
/**將剛剛讀取的數據包寫到本地文件中去*/
fos.write(buffer,0,size);
fos.flush();
/**將已接收到文件的長度+size*/
count+=size;
System.out.println("伺服器端接收到數據包,大小為"+size);
}
}catch(FileNotFoundExceptione){
System.out.println("伺服器寫文件失敗");
}catch(IOExceptione){
System.out.println("伺服器:客戶端斷開連接");
}finally{
/**
*將打開的文件關閉
*如有需要,也可以在此關閉socket連接
**/
try{
if(fos!=null)
fos.close();
}catch(IOExceptione){
e.printStackTrace();
}//catch(IOExceptione)
}//finally
}//publicstaticvoidmain(String[]args)
}//publicclassServerReceive