基于Socket实现Android(java)与C#的同步通信

2015-04-02 14:03何诚等
无线互联科技 2015年2期

何诚等

摘 要:基于Socket的通信机制,阐述了Java和C#语言通过Socket编程来互相通信的步骤,并给出了一种C/S模式的Socket通信系统框架,该框架解决了通过USB连接的安卓应用和Windows桌面应用之间通信的问题,达到了不同平台下文件和不同语言的对象的互传。

关键词:Socket编程;Java;C#;Json;数据同步

1 引言

随着Android智能手机市场的扩大,基于Android系统的应用程序也越来越多。Android程序多以Java语言为基础进行开发,而在Windows平台上,c#已经成为开发桌面程序的主流平台。在一些应用场景中,需要Android设备与装有Windows系统的计算机通过USB连接,用C#编写客户端,java编写服务器,实现跨平台的通信。

而标准的Socket方法可以实现任何平台和任何进程之间的Socket通信,在PC和Android手机通过USB连接的情况下,可用Android系统的ADB工具进行端口的转发,从而使两端设备的Socket连通。

2 实现通信的关键技术

基于以下技术,实现满足需求的Socket通信系统框架:

2.1 Socket通信技术

Socket是一种套接字规范,利用客户/服务器模式,解决了进程之间建立通信连接的问题。安装了TCP协议软件和实现了套接字规范的设备之间即可通过Socket进行通信。套接字之间连接的过程需要经过这三个步骤:服务端开启监听,客户端发出请求,服务端通过监听收到请求后再确认连接。两端连接上后即可进行数据传输的操作。

Socket有两种操作方式,一种使用TCP协议,在本系统中要求数据传输的准确性,因此采取使用TCP协议的来传输数据的方法。

2.2 C#中的套接字编程

Microsoft.Net.Framework的名字空间System.Net和System.Net.Socket包含丰富用以网络编程的类,其中Socket类为实现套接字网络编程提供了大量方法。

通过Encoding.UTF8.GetBytes(String),C#可以将将字符串转换为UTF-8字节数组,通过Encoding.UTF8.GetString(bytes[],0,Length)将UTF-8字节数组转换为字符串。

在创建Socket对象后,可通过Send方法发送字节数组形式的数据,或使用Receive方法接收字节数组数据,再用以上方法转换为相应字符串进行处理。

2.3 Java中的套接字编程

Java在包java.net中提供了两个类,Socket和ServerSocket。服务端和客户端之间先建立Socket之间的连接,之后进行通信。在服务端新建ServerSocket对象,循环执行accept方法来监听设备指定的端口,当客户端有Socket来连接它时,它会接受该Socket的连接请求,同时在服务端建立一个对应的Socket对象并和它进行通信。这样两边各一个互相连接的Socket对象,通过两个socket传递数据实现了通信。

Java同样提供了字节数组和字符串之间的进行转换的方法,将字节数组转换为字符串的过程如下:

String string = new String(charArray, 0, length);

字符串转换为字节数组的过程如下:

byte[] byte = strContent.getBytes("UTF-8");

2.4 用Json将对象序列化

除了传输文件数据外,在面向对象编程中,发送的数据要用实体类封装,将封装的对象存入List()泛型集合中,可以通过序列化List对象来灵活的封装和传递大量数据。

因为跨语言的需要,用Java或C#一方自己的序列化方式是行不通的,而Json提供了一个通用的序列化格式。

C#可以用开源的项目JSON.NET,在项目中添加引用:using Newtonsoft.Json;和using Newtonsoft.Json.Converters即可使用以下方法:

序列化:

JsonConvert.SerializeObject(string);

反序列化:

JsonConvert.DeserializeObject(obj);

Java可以用开源项目google-gson,在项目中导入这个项目的第三方jar包,然后添加引用:import com.google.gson.Gson;就可使用以下方法:

序列化:

Gson gson=new Gson();

String s=gson.toJson(obj);

反序列化:

Gson gson=new Gson();

Object obj=gson.fromJson(s,Object.class);

2.5 C#启动cmd调用Android系统的调试工具ADB

通过C#名字空间System.Diagnostics提供的Process类调用Windows系统

的cmd.exe,在USB连接的情况下,执行“adb forward tcp:12581 tcp:10087”命令转发端口信息,并通过“adb shell am broadcast -a”命令发送一个广播给Android应用程序,以启动Android程序相应的service,在service中编写socket实现通信。

3 数据同步方法实现流程

根据以上列举的关键技术来设计一个实现Android应用程序和桌面程序通信的模型,分为C#客户端和Java服务端两部分:

3.1 客户端程序编写流程如下

⑴C#通过ADB发送Android系统的BroadCast广播,来启动Android的Service后台程序。

⑵新建一个Socket对象,Android默认手机端的IP为“127.0.0.1”,因此以“127.0.0.1”和指定的端口号为参数,执行该对象的Connect方法。

⑶发送对象时将要传递的对象用Json序列化函数JsonConvert.SerializeObject()序列化为字符串,再将字符串转换为字节数组,最后通过Socket对象的Send方法发送数据。

⑷接收数据时执行Socket对象的Receive方法,将得到的字节数组转换为字符串,再用JsonConvert.DeserializeObject()方法反序列化字符串得到对象。

⑸程序关闭时执行Socket对象的close()方法关闭socket连接,并发送关闭service的广播。

3.2 服务端程序编写流程如下

⑴编写一个Android端继承了Service类的后台运行的程序,作为服务器端,再编写一个继承BroadcastReceiver类的程序来接收广播,当接收到客户端发来的广播时来打开或关闭Service。

⑵Service启动的时候以固定端口号作为参数新建一个SocketServer的对象,当有客户端的socket连接时,通过SocketServer的accept方法新建Socket类的对象。

⑶新建BufferedOutputStream对象来发送Socket要发送的数据,新建BufferedInputStream对象来接收Socket对象接收的的数据。

⑷新建Gson对象,执行该对象的序列化和反序列化方法,将要发送的数据转换为字节数组,将接收的字节数组转换为对象。

⑸Service关闭时关闭通讯流和Socket。

4 结语

给出了解决C#平台和基于java的Android平台的同步通信的一个方案,总结了实现该方案所用到的技术基础,即Java和c#系统具有基于Socket的灵活通信机制,并在格式方面可以通过Json进行转换。

[参考文献]

[1]周培.基于Socket的即时通信系统的研究与实现[D].广州:华南大学,2010.

[2]李杨,耿昌宇,张丽芬.基于Socket通讯模式下的跨平台数据同步[J].北京理工大学学报,2002(2).

[3]米洪,郑莹.基于SOCKET和JNI的Java与C++通信对比研究[J].软件导刊,2009(1).