天天看點

消息(2)——聯機下的資料傳輸,socket傳輸字串及複雜類型

資料傳輸是個很大的概念。我不是從理論的角度去記錄随筆,隻是把互聯傳輸中的概念簡化到消息的位面。以便于對分布傳輸中的消息進行一下剖析,加深印象。

對處于脫機狀态下的終端來說,資料的傳輸可以通過中間媒體進行中介傳輸。但在聯機情況下,可以不必通過第三方的介入,僅用的就是其中的資料線。這個概念很容易了解:

1 一塊幹電池,兩根導線,一個直流電燈泡。電池和燈泡可以看做是脫機情況下的兩個終端,而電流就是資料。當兩者相連,電燈泡就能亮(一切狀态假設成立)。兩者相連就能有電流通過,這個原理是懂的。因為電壓的原因,電流會有一個完整的回路。(更深的不探讨)。這裡互聯的兩上終端如果要有電流的傳輸,那麼至少兩個必要的因素:資料線和電壓。

2 在農村澆灌莊稼地。主要的步驟是:拉電閘,抽水機把地下水抽上來,然後由壟溝把水導到地裡進行灌溉。這裡也是有必要的因素:水泵叫水,因為水壓的原因使水向前流,有通到地裡的壟溝。

聯機中的終端要進行資料傳輸要有一些必要的條件,例如其中的通道,使資料進行傳輸的動力等等。

協定是什麼?

(引百度知道)在計算機範疇内:計算機通信網是由許多具有資訊交換和處理能力的節點互連而成的,要使整個網絡有條不紊地工作,就要求每個節點必須遵守一些事先約定好的有關資料格式及時序等的規則。 這些為實作網絡資料交換而建立的規則、約定或标準就稱為網絡協定。

協定是通信雙方為了實作通信而設計的約定或通話規則。

協定總是指某一層的協定。準确地說,它是在同等層之間的實體通信時,有關通信規則和約定的集合就是該層協定,例如實體層協定、傳輸層協定、應用層協定。

其實從字面上,我們都能了解所謂的協定是什麼,這種意義對計算機通信而言也是有意義的。平常所熟知的協定有Http,Tcp/Ip,UDP等。協定是要對通信雙方都有效的約定,而雙方也都要符合這種約定,不管是軟體環境還是硬體環境。

資料傳輸

計算機通信為的就是資料傳輸,但資料有所有同,從實體上都是二進制或者說最終在實體媒體上都是二進制。

在區域網路内,檔案共享,列印機共享是最常見的。廣域網中,電子郵件,實時通信,網頁預覽,資源下載下傳,Ftp上傳等。

它們的終端都要遵守共同的約定。

如果現在A和B要進行資料傳輸,例如A要把自己的客戶名單傳輸到B上,

那麼能過Http協定:

B架設網站伺服器來釋出Html,A通過http來通路B網站上的客戶名單導入頁,然後導入自己的客戶名單并送出,資料通過Http協定Post或Get方式把資料傳送到B,B在收到資料後進行存儲

在Tcp/Ip協定下:

B建立套接字監聽位址和端口,A與B建立連接配接,然後向B傳遞資料,B收到資料後進行存儲。

而http協定中傳輸的是http協定包,包中包含着傳遞的資料,tcp協定中傳輸的tcp包,可能隻是一個字元串。

(1)通過Socket傳遞字元串

服務端:

static void Main(string[] args)

{

    IPAddress address = IPAddress.Parse("192.168.1.98");

    IPEndPoint _address = new IPEndPoint(address, 65000);

Socket socket = new Socket(AddressFamily.InterNetwork,

SocketType.Stream, ProtocolType.Tcp);

    socket.Bind(_address);

    socket.Listen(20);

    byte[] bb=new byte[255];

    while (true)

    {

Socket ss = socket.Accept();

ss.Receive(bb);

Console.WriteLine(Encoding.UTF8.GetString(bb));

    }

}

用戶端:

public void TestSocket()

    IPEndPoint _address = new IPEndPoint(address,65000);

    socket.Connect(_address);  

    string strMessage = "test123";

    byte[] bb = Encoding.UTF8.GetBytes(strMessage);

    socket.Send(bb);

    Console.WriteLine("Sent: {0}", strMessage);

這裡傳遞的是最簡單的字元串。

在兩端進行圖檔傳遞也可以參考消息(1)中的内容來實作。

(2)傳遞客戶資訊

對于傳遞客戶資訊,這裡的方法就是轉換為字串,轉換為可解析的字串,例如json。這裡通過json.net這個第三方json序列化和反序列化工具來實作對客戶資訊的序列化及反序列化。

IPAddress address = IPAddress.Parse("127.0.0.1");

IPEndPoint _address = new IPEndPoint(address, 65000);

socket.Bind(_address);

socket.Listen(20);

byte[] bb=new byte[350];

while (true)

    Socket ss = socket.Accept();

    ss.Receive(bb);

    Customer customer = new Customer();

    MemoryStream ms=new MemoryStream();

    ms.Read(bb,0,bb.Length);

    string strJson = Encoding.Default.GetString(bb);

    char c = '\0';

    var p = from q in strJson where q != c select q;

    char[] chs = p.ToArray<char>();

    strJson = new string(chs);

    try

        customer=JsonConvert.DeserializeObject<Customer>(strJson);

    catch

    { }

    ms.Close();

    Console.WriteLine(customer.Unid);

其中對json.net的更多内容可見官網我的部落格上的幾篇随筆:

http://james.newtonking.com/projects/json-net.aspx http://www.cnblogs.com/jams742003/archive/2010/03/03/1677288.html

在用戶端:

public void TestCustomer()

    Customer customer = new Customer

Unid = 13,

CustomerName = "Songjiang",

CreateTime = DateTime.Now,

Telephone = new Call

{ Mobile = "1111111", FirmCall = "2222", HomeCall = "3333" }

    };

    string strJson = JsonConvert.SerializeObject(customer);

byte[] bb = Encoding.Default.GetBytes(strJson);

    IPAddress address = IPAddress.Parse("127.0.0.1");

    socket.Connect(_address);

    Console.WriteLine("發送完畢");

    socket.Close();

因為這個客戶類的原因,使得在服務端和用戶端都有有這個類。

在傳遞簡單資訊的時候,能很友善的傳遞,因為它們都是做為基元類型存在,但對于複雜類型,例如類類型,則要對兩端都要有這個類。

在這個例子中,socket傳遞的包是帶有一個json大串的字元串。通過抓包的工具,拿下這個包的内容是:

{"Unid": 13,"CustomerName ":"Songjiang","CreateTime":"

\/Date(1269998944484 +0800)\/","Telephone":

{"HomeCall ":"3333","Mobile ":"1111111",

"FirmCall":"2222"}}

現在有這麼一種情況,在.net環境下這個資料傳遞是可以實作,但如果用到别的環境還能這樣嗎?

其實對于這個例子,它是可以的,因為json也是一種資料交換格式,是一種輕量級的。同時,可以利于機器的生成和解析。

還有一種格式就是xml格式,通過它也可以進行資料交換。這邊是一個對客戶資訊進行xml化進行傳輸。

public void TestCustomerXml()

Telephone = new Call {

Mobile = "1111111",

FirmCall = "2222",

HomeCall = "3333" }

    //建立xml

    XDocument doc = new XDocument();

    doc.Add(new XElement("Customers"));

    doc.Element("Customers").Add(new XElement("Customer"));

    doc.Element("Customers").Element("Customer").Add(

new XElement("Unid",customer.Unid),

new XElement("CustomerName",customer.CustomerName),

new XElement("CreateTime",customer.CreateTime),

new XElement("Telephone")

);

doc.Element("Customers").Element("Customer").Element("Telephone").

Add(

new XElement("Mobile",customer.Telephone.Mobile),

new XElement("FirmCall",customer.Telephone.FirmCall),

new XElement("HomeCall",customer.Telephone.HomeCall)

    string strXml = doc.ToString();

    byte[] bb = Encoding.Default.GetBytes(strXml);

    IPAddress address = IPAddress.Parse("192.168.1.105");

用戶端建立一個描述客戶資料的xml文檔,然後向伺服器送出。

    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    byte[] bb = new byte[350];

Customer customer = new Customer();

MemoryStream ms = new MemoryStream();

ms.Read(bb, 0, bb.Length);

string strXml = Encoding.Default.GetString(bb);

char c = '\0';

var p1 = from q in strXml where q != c select q;

char[] chs = p1.ToArray<char>();

strXml = new string(chs);

XDocument doc=XDocument.Parse(strXml);

var p = from q in doc.Element("Customers").Element("Customer").Elements() select q;      

customer = new Customer

Unid = Convert.ToInt32(

p.Where(x => x.Name == "Unid").First<XElement>().Value),

             CustomerName = (p.Where(x => x.Name == "CustomerName").

First<XElement>().Value).ToString(),

             CreateTime = Convert.ToDateTime(p.

Where(x => x.Name == "CreateTime").

First<XElement>().Value),

             Telephone = new Call {

Mobile = p.Where(y => y.Name == "Telephone").

First<XElement>().Elements().Where(x => x.Name == "Mobile").

First<XElement>().Value,

FirmCall = p.Where(y => y.Name == "Telephone").

First<XElement>().Elements().Where(x => x.Name == "FirmCall").

HomeCall = p.Where(y => y.Name == "Telephone").

First<XElement>().Elements().Where(x => x.Name == "HomeCall").

First<XElement>().Value

};

ms.Close();

Console.WriteLine(customer.Unid);

服務端接收到xml後進行解析,分離資料。

服務端與用戶端都以xml格式進行資料的解析和生成,xml就是他們共同的約定。

部落格園大道至簡

http://www.cnblogs.com/jams742003/

轉載請注明:部落格園