消息(2)——联机下的数据传输,socket传输字串及复杂类型

本文涉及的产品
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
云解析 DNS,旗舰版 1个月
简介: 数据传输是个很大的概念。我不是从理论的角度去记录随笔,只是把互联传输中的概念简化到消息的位面。以便于对分布传输中的消息进行一下剖析,加深印象。   对处于脱机状态下的终端来说,数据的传输可以通过中间介质进行中介传输。

数据传输是个很大的概念。我不是从理论的角度去记录随笔,只是把互联传输中的概念简化到消息的位面。以便于对分布传输中的消息进行一下剖析,加深印象。

 

对处于脱机状态下的终端来说,数据的传输可以通过中间介质进行中介传输。但在联机情况下,可以不必通过第三方的介入,仅用的就是其中的数据线。这个概念很容易理解:

1 一块干电池,两根导线,一个直流电灯泡。电池和灯泡可以看做是脱机情况下的两个终端,而电流就是数据。当两者相连,电灯泡就能亮(一切状态假设成立)。两者相连就能有电流通过,这个原理是懂的。因为电压的原因,电流会有一个完整的回路。(更深的不探讨)。这里互联的两上终端如果要有电流的传输,那么至少两个必要的因素:数据线和电压。

2 在农村浇灌庄稼地。主要的步骤是:拉电闸,抽水机把地下水抽上来,然后由垄沟把水导到地里进行灌溉。这里也是有必要的因素:水泵叫水,因为水压的原因使水向前流,有通到地里的垄沟。

 

联机中的终端要进行数据传输要有一些必要的条件,例如其中的通道,使数据进行传输的动力等等。

 

协议是什么?

(引百度知道)在计算机范畴内:计算机通信网是由许多具有信息交换和处理能力的节点互连而成的,要使整个网络有条不紊地工作,就要求每个节点必须遵守一些事先约定好的有关数据格式及时序等的规则。 这些为实现网络数据交换而建立的规则、约定或标准就称为网络协议。

协议是通信双方为了实现通信而设计的约定或通话规则。

协议总是指某一层的协议。准确地说,它是在同等层之间的实体通信时,有关通信规则和约定的集合就是该层协议,例如物理层协议、传输层协议、应用层协议。

 

其实从字面上,我们都能理解所谓的协议是什么,这种意义对计算机通信而言也是有意义的。平常所熟知的协议有HttpTcp/IpUDP等。协议是要对通信双方都有效的约定,而双方也都要符合这种约定,不管是软件环境还是硬件环境。

 

数据传输

计算机通信为的就是数据传输,但数据有所有同,从物理上都是二进制或者说最终在物理介质上都是二进制。

在局域网内,文件共享,打印机共享是最常见的。广域网中,电子邮件,实时通信,网页预览,资源下载,Ftp上传等。

它们的终端都要遵守共同的约定。

 

如果现在AB要进行数据传输,例如A要把自己的客户名单传输到B上,

那么能过Http协议:

B架设网站服务器来发布HtmlA通过http来访问B网站上的客户名单导入页,然后导入自己的客户名单并提交,数据通过Http协议PostGet方式把数据传送到BB在收到数据后进行存储

Tcp/Ip协议下:

B建立套接字监听地址和端口,AB建立连接,然后向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()

{

    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.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 socket = new Socket(AddressFamily.InterNetwork,

SocketType.Stream, ProtocolType.Tcp);

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");

    IPEndPoint _address = new IPEndPoint(address, 65000);

Socket socket = new Socket(AddressFamily.InterNetwork,

SocketType.Stream, ProtocolType.Tcp);

 

    socket.Connect(_address);

    socket.Send(bb);

    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()

{

    Customer customer = new Customer

    {

Unid = 13,

CustomerName = "Songjiang",

CreateTime = DateTime.Now,

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");

    IPEndPoint _address = new IPEndPoint(address, 65000);

Socket socket = new Socket(AddressFamily.InterNetwork,

SocketType.Stream, ProtocolType.Tcp);

 

    socket.Connect(_address);

 

    socket.Send(bb);

    Console.WriteLine("发送完毕");

    socket.Close();

}

客户端创建一个描述客户数据的xml文档,然后向服务器提交。

 

服务端:

static void Main(string[] args)

{

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

 

    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[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 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").

First<XElement>().Value,

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/

转载请注明:博客园

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
Sqoop 企业级大数据迁移方案实战
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
目录
相关文章
|
12月前
|
存储 网络协议 Java
网络通信的核心机制:Socket如何实现高效数据传输(上)
网络通信的核心机制:Socket如何实现高效数据传输
|
19天前
|
Python
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
使用Python的socket库实现客户端到服务器端的图片传输,包括客户端和服务器端的代码实现,以及传输结果的展示。
90 3
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
|
5月前
|
网络协议
逆向学习网络篇:通过Socket建立连接并传输数据
逆向学习网络篇:通过Socket建立连接并传输数据
55 0
|
5月前
|
监控 网络协议 Java
Java Socket编程 - 基于TCP方式的二进制文件传输
Java Socket编程 - 基于TCP方式的二进制文件传输
42 0
|
6月前
|
网络协议 Java 网络安全
【计算机网络】—— Socket通信编程与传输协议分析
【计算机网络】—— Socket通信编程与传输协议分析
|
6月前
|
网络协议 安全 Python
socket客户端和服务端,文件的传输
socket 实现,客户端和服务端,文件的传输
89 1
|
存储
14.3 Socket 字符串分块传输
首先为什么要实行分块传输字符串,一般而言`Socket`套接字最长发送的字节数为`8192`字节,如果发送的字节超出了此范围则后续部分会被自动截断,此时将字符串进行分块传输将显得格外重要,分块传输的关键在于封装实现一个字符串切割函数,将特定缓冲区内的字串动态切割成一个个小的子块,当切割结束后会得到该数据块的个数,此时通过套接字将个数发送至服务端此时服务端在依次循环接收数据包直到接收完所有数据包之后在组合并显示即可。
65 0
14.3 Socket 字符串分块传输
14.7 Socket 循环结构体传输
在上述内容中笔者通过一个简单的案例给大家介绍了在套接字编程中如何传递结构体数据,本章将继续延申结构体传输,在某些时候例如我们需要传输一些当前系统的进程列表信息,或者是当前主机中的目录文件,此时就需要使用循环结构体传输功能,循环传输结构体的关键点在于,客户端发送结构体数据之前需要通过一次通信来告诉服务端需要接收的次数,当服务端接收到次数时则可利用接收计数器依次循环接收数据直到客户端完整所有数据包的发送。
43 0
14.7 Socket 循环结构体传输
14.6 Socket 应用结构体传输
当在套接字编程中传输结构体时,可以将结构体序列化为字符串(即把结构体的所有成员打包成一个字符串),然后将字符串通过套接字传输到对端,接收方可以将字符串解析为结构体,然后使用其中的成员数据。这种方法通常被称为序列化(Serialization)和反序列化(Deserialization),本章中我们可以采用将一个结构体序列化为一个纯字符串,然后将该字符串通过套接字传输给对端,当对端收到后只需要将字节序强制转换为对等的结构体指针即可实现对该结构的解析。
63 0
14.6 Socket 应用结构体传输
|
12月前
|
编解码 Java 网络安全
网络通信的核心机制:Socket如何实现高效数据传输(下)
网络通信的核心机制:Socket如何实现高效数据传输