时间:2023-05-29 18:03:38
开篇:写作不仅是一种记录,更是一种创造,它让我们能够捕捉那些稍纵即逝的灵感,将它们永久地定格在纸上。下面是小编精心整理的12篇socket通信,希望这些内容能成为您创作过程中的良师益友,陪伴您不断探索和进步。
关键词: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#中的套接字编程
.Framework的名字空间和.Socket包含丰富用以网络编程的类,其中Socket类为实现套接字网络编程提供了大量方法。
通过Encoding.UTF8.GetBytes(String),C#可以将将字符串转换为UTF-8字节数组,通过Encoding.UTF8.GetString(bytes[],0,Length)将UTF-8字节数组转换为字符串。
在创建Socket对象后,可通过Send方法发送字节数组形式的数据,或使用Receive方法接收字节数组数据,再用以上方法转换为相应字符串进行处理。
2.3 Java中的套接字编程
Java在包中提供了两个类,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#可以用开源的项目,在项目中添加引用: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.
关键词:Java;Socket;多客户并发;网络通信
中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)20-30253-03
Design & Implement of Chat System Based on Socket Multi-user Parallel Communication
MO Zu-qin, OUYANG Yan-jie, MA Kang
(Dept of Computer Eng, Shiyan Technical Institute Eng, Shiyan 442000, China)
Abstract: As internet technic and computer language develop, more and more programmers make use of Java to compile net programme. This paper introduces the mechanism of communications and using the combination of Java language, Socket API technic and the multithreading to implement chat system in which multi-user and server can communicate parallel.
key words: Java; Socket; multi-user send parallel; Net communication
1 引言
Java是一种可以编写跨平台应用软件的面向对象的程序设计语言,网络应用是Java语言取得成功的领域之一,它已经成为现在Internet上最流行的一种编程语言。网络编程的目的就是直接或间接地通过网络协议与其它计算机进行通讯。两台计算机通讯需解决两个主要问题:一是如何准确定位网络上的主机;二是找到主机后如何可靠有效地进行数据传输。
Java语言作为网络编程语言,提供了强大的网络编程接口。针对网络通信的不同层次,Java提供的网络功能有四大类:InetAddress、URL、Socket、Datagram。Socket是Internet使用的协议组TCP/IP的组合,实现了两台主机之间通过端口进行网络通信。包中提供Socket类,隐藏了Socket的实现细节,不需要开发者编写接口程序,而可以快速的实现网络的通信。[1]
2 Socket的通信
2.1 Socket通信机制
在Java中,可以使用两种Socket方式,即流式Socket和数据报式Socket。流式Socket提供了双向的、有序的、无重复、可靠的的数据流服务,采用的是一种TCP协议。数据报式Socket支持双向的数据流,但不保证是可靠的、有序的、无重复的传输,采用的是UDP协议。[1]两种Socket相比较而言,流式Socket具有较高的安全性,但有一定的额外开销。而数据报式Socket与之相反。笔者根据实际情况采用的是流式Socket方式。
基于TCP协议的流式Socket实现网络通信的类有两个:在客户端的Socket类和在服务器端的ServerSocket类。无论一个Socket通信程序的功能多么齐全,程序多么复杂,Socket基本
结构都是一样的,都包括以下四个基本步骤:
(1)在客户端和服务器端创建Socket和ServerSocket实例;
(2)打开连接到Socket的输入/输出流;
(3)利用输入/输出流,按照一定的协议对Socket进行读/写操作;
(4)关闭输入/输出流和Socket。
Socket通信机制框图见图1。
2.2 Socket的多客户端并发通信
支持多个客户端的Socket通信实现方法有多种:方法一,在一台计算机上一次启动多个服务器程序(端口号必须不同);方法二,将服务器程序写成多线程的,不同处理线程为不同的客户服务,主线程只负责循环等待,处理线程负责网络连接,接收客户输入的信息。
实现多个客户与服务器并发通信,就像服务器与自己连接一样,笔者认为最好引入多线程机制。多线程正好是Java提供的一个重要机制,支持多个程序并发执行。服务器端每当建立一个新的Socket连接,主线程就启动一个新的线程,负责服务器与客户端的通信;而主线程继续等待下一个客户端的连接。当客户端断开连接后,子线程释放其占用的所有Socket资源[3]。多线程支持多客户端的具体框图见图2。
3 多客户端聊天程序的设计
系统主要分为两大部分:TCP服务器Server和客户端Client。
3.1 服务器端程序编写
服务器端等待用户连接,如有用户发送连接请求后,创建一个用户实例,记录客户端的相关信息,维护与该用户的连接。根据聊天的接收人信息,再将接收的数据传输给客户端。当用户断开连接时,关闭用户实例,断开此用户连接。[2]主要步骤如下:
(1) 启动服务器
try {
server=new ServerSocket(port);//初始化服务器套接字
while(true){socket=server.accept(); //等待客户连接
System.err.println(socket.getInetAddress()+"连接\n"); //得到客户机地址
Client client=new Client(socket);//实例化一个客户线程
clients.addElement(client);//增加客户线程到向量中
client.start(); //启动线程
notifyChatRoom(); //监视聊天室连接变化
} }catch(Exception ex) {
ex.printStackTrace(); //输出出错信息}
(2) 更新在线用户
for(int i=0;i
{//elementAt方法返回在特定位置的元素,返回的元素为Object对象
Client c=(Client)clients.elementAt(i);
newUser.append(":"+c.name);//客户端姓名字符串,取得客户端的名字
}sendClients(newUser); //把取得的客户端名字发送给每个客户端
(3) 多线程的实现
聊天室的服务器采用多线程实现,每当一个新的用户连接到服务器时,就实例化一个新的线程来与该客户端通信。Client类负责维护客户端的相关信息,比如IP地址、聊天室中的用户名、连接端口等,并实现了信息发送的send方法。主要代码如下。
//得到输入流
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintStream ps=new PrintStream(s.getOutputStream()); //得到输出流
String info=reader.readLine(); //读取接受到的信息
ps.println(msg); //输出信息
ps.flush();
public void run(){while(true){
String line=null;
try{line=reader.readLine();//读取数据流
}catch(IOException ex){
ex.printStackTrace(); //输出错误信息
MyChatServer.disconnect(this); //断开连接
MyChatServer.notifyChatRoom(); //更新信息
return;}
……
3.2 客户端程序编写
提供良好的用户界面,便于用户连接、查看在线用户、发送信息。当与服务器建立连接后,发送聊天信息。同时,检测服务器端有无数据发送,接收数据,更新显示。
(1)界面设计(代码略)
(2)事件处理
建立连接的事件处理代码:
try{if (socket==null){
socket= new Socket(InetAddress.getLocalHost(),5656); //实例化一个套接字
ps=new PrintStream(socket.getOutputStream());//获取输出流
StringBuffer info=new StringBuffer("INFO: ");
String userinfo=jTextField1.getText()+":"+InetAddress.getLocalHost().toString();
ps.println(info.append(userinfo)); //输出信息
ps.flush();
listen=new Listen(this,jTextField1.getText(),socket); //实例化监听线程
listen.start(); /启动线程
}}catch (Exception ex){}
发送信息的代码:
if(socket!=null){StringBuffer msg=new StringBuffer("MSG: ");
String msgtxt=new String(jTextField2.getText());
ps.println(msg.append(jTextField2.getText())); //发送信息
ps.flush();
(3)监听线程的实现
Listen类用于与服务器进行通信,并维护一些连接信息。部分代码如下。
public Listen(MyChatClient p,String n,Socket s) {
……
public void run(){
String msg=null;
while(socket!=null){
try{msg=reader.readLine();//读取服务器端传来信息
}catch(IOException ex){
client.disconnect(); //出错则断开连接
}if (msg==null) { /从服务器传来的信息为空则断开此次连接
client.listen=null;
client.socket=null;
client.list1.removeAll();
return;}……}}
3.3 运行结果
本程序的运行界面如图3所示。
4 结束语
Java语言具有平立、面向对象、多线程、简单性、解释性等许多优点,是目前广泛流行的编程语言。笔者使用Socket与多线程机制相结合的方法,编写了简便的客户端与服务器的并发通信聊天程序。此程序具有成本低、节省带宽和跨平台可移植性的优点。随着宽带网络的进一步发展,我们还可以开发基于Socket的多人视频聊天软件。
参考文献:
[1] 王静,曲凤娟.基于Socket的多用户并发通信的设计[J].福建电脑,2007(3):164.
[2] 袁海燕,王文涛.Java实用程序设计100例[M].北京:人民邮电出版社,2005:226-229.
关键词:网络通信;Linux;Windows;Socket;UDP
中图分类号:T330文献标识码:A文章编号:1009-3044(2009)27-7788-02
Application of Network Communication Technology in Ultrasonic Testing System
SONG Jing
(College of Information Science and Technology, Nanjing University of Aeronautics and Astronautics, Nanjing 210016, China)
Abstract: The network communication has the broad application in actual. Combining with the application in an ultrasonic testing system, this paper discussed the key techniques of the network communication between embedded operating system Linux and windows. And specified the method of network communication of different operating system between Linux and Windows by using Socket.
Key words: Network communication;Linux;Windows;Socket;UDP
在工业控制,智能家电等领域,嵌入式系统已成为各种具体应用的基础。对于有联网需求的应用,在工业领域我们通常使用各类工业现场总线来连接嵌入式系统及各个主机;而对于另一些场合,往往使用TCP/IP网络以简化网络结构,降低成本。本文就是针对这类需求,探讨了在超声波探伤系统中嵌入式Linux系统与Windows主机实现通信的方法。
1 开发环境
本文结合的某超声波探伤系统的硬件框图如图1。
该系统是基于PC机的超声探伤系统。其中模拟部分负责超声波信号的发生和接收,FPGA子系统负责高速信号处理以及各种逻辑控制,嵌入式子系统负责各种硬件设备的控制和管理。超声波触发电路激励探头产生超声波信号并接收其回波,得到的信号经过滤波、高频放大、高速AD转换、高速缓存等处理,然后通过PCI总线送入PC机中。同时在 PC机上采用VC++开发了超声波无损检测信号分析系统,实现波形的实时显示、用户指令操作、波形的后续处理等操作。
数据传输是超声波探伤系统的重要任务之一,为了使系统具有通信功能,本设计采用了以太网来完成此项功能,以太典型的应用形式是Ethernet + TCP/IP,即在由以太网构建的底层传输网络上采成为通用标准的网络传输协议TCP/IP进行数据通信,这是当今最流行,应广泛的以太网通信方式。
2 网络通信原理
2.1 Socket介绍
Socket是为方便开发人员进行TCP/IP程序开发,而为TCP/IP协议开发的一组应用程序接口(API),它是网络通信中应用进程和网络协议之间的接口。Socket在所有网络操作系统和网络应用程序中都是必不可少的。
socket函数原型为:int socket(int domain, int type, int protocol)。
常用的Socket类型有两种:针对于面向连接的TCP服务应用的流式Socket和对应于无连接的UDP服务应用的数据报式Socket。
2.2 网络通信框图
图2是系统在 TCP/IP协议下通过网络进行通信的框图。服务器端和客户端都通过Socket接口相互问进行通信。
根据建立连接的类型,分成面向连接和无连接两种,分别对应TCP和UDP协议;两个系统通过各自的网络接口设备物理上互连,在传递数据信息时,在上层建立起UDP套接字虚连接。
3 网络通信实现
针对嵌入式设备通讯主要是发送接收一些实时数据信息及指令,这里选择了相对高效的UDP传输协议。
由于使用UDP协议来传输数据,可能会因物理网络或者其它原因丢失数据包或数据包在传输过程中损坏,可以利用一段时间内的多次发送来覆盖这种小概率的数据出错;另外一种较好的解决方法是将此纠错处理交给应用层即所编写的程序来应对,比如在Linux端发送消息时即确定好一个关于本次发送字符串的校验标志,然后Windows端接收到后先对这个字符串做相同的校验处理,结果与取出的标志相比较,同则接受这个包,并做进一步处理,不同则认为包在传输过程中已损坏,舍弃等待下一个包到达。
3.1 Linux下网络通信程序设计
1) 创建Socket
sock = socket(AF_INET, SOCK_DGRAM, 0);创建Socket
2) 配置Socket
//先对服务器地址server_addr等数据结构和字节顺序进行初始化。
bind(sock, (struct sockaddr *) & client_addr, sizeof(client_addr))// 利用bind()函数绑定端口和地址信息
3) 数据通信
recvfrom(sock,(char *)&recvPacket,sizeof(RecvPacket), 0,(struct sockaddr *)&server_addr,&addr_len);// 接收数据
sendto(sock,(char *)&sendPacket,sizeof(SendPacket), 0,(struct sockaddr *)&server_addr,addr_len);//发送数据
在编译之前我们需要在系统里安装g++、gcc,它们就是Linux下的C++/C的编译器,这里我们使用g++来编译C++程序。该程序利用双线程来实现收发数据,在Linux下,编译一个多线程的程序命令为:g++ -lpthread -o file file.c
也可以将编译过程写入makefile中,定义相关参数及使用静态链接,最后编译,连接,产生目标代码。
3.2 Windows下网络通信程序设计
Windows主机部分作为监控端,不仅需要实现数据信息的实时接收,处理与转发,还需要有一良好的人机交互界面,采用VisualC++6.0中的MFC可以方便的创建人机交互界面,而且MFC封装了WinSock类库,可以很方便地开发基于TCP/I P的网络应用程序,其服务器端监控程序的开发步骤如下 :
1)创建套接字 ServerSocket 。
ServerSocket=socket(AF_INET,SOCK_DGRAM,0);
2)为套接字分配地址。
//初始客户端端的地址和端口信息
//初始化自己的地址和端口信息并与socket绑定
bind(m_socket,(SOCKADDR*)& addrSrv,sizeof(SOCKADDR));
3)数据通信
Socket配置完成后,就可以通过send()和recv()发送和接收数据了,函数模型与Linux下函数相同。
recvfrom(sock,(char*)&recvPacket,sizeof(RecvPacket),0,(SOCKADDR*)&addrClient,&len)
sendto(sock,(char *)&sendPacket,sizeof(SendPacket),0,(SOCKADDR*)&addrClient,len)
4 结束语
本文着眼于网络通信在超声波探伤系统中的应用,使其能够进行网络通信,实现远程监控、网络互连、数据传输。基于TCP/IP协议的以太网通信快速准确的实现了Window和Linux之间的数据传输。利用以太网简单方便、嵌入式操作系统Linux的开放和低价、再加上Windows良好的人机界面,通过Socket编程实现网络通信,将这三者很好的结合在一起,是智能化检测仪器的发展方向。本课题的研究为高性能的网络化超声波无损检测技术奠定了良好的基础,具有一定的实际意义。
参考文献:
[1] 强建国,马晓,杨东亚,等.用Windows套接字实现双向Internet实时通讯[J].兰州理工大学学报,2005,31(5).
[2] 郎锐,罗发根.Visual C++网络通信程序开发指南[M]. 北京:机械工业出版社,2004.
[3] er,David L.Stevens.TCP/IP客户一服务器编程与应用[M].北京:清华大学出版社,2004.
[4] 张树兵,庞勇. Winsock网络通信程序的开发[J]. 华北工学院学报, 2002,23(2).
关键词:车载终端;通信软件系统;Socket
中图分类号:TP311
中国经济的快速发展使得城市机动化的加速,城市出现了交通拥堵,流量增加,环境污染,能源短缺等问题,适当的运输调度和安全管理成为运输业务和其他部门的首要问题。许多城市政府每年都会投入大量的人力,物力,用以改善和解决城市交通问题。作为电子设备的车载终端具有完善的功能,并且能够用在最短的时间内获得及时准确的导航信息和交通信息。车载终端,能够给家人和朋友们提供一个有线的游戏娱乐的交流平台。移动通信技术的发展和全球定位系统(GPS)技术和持续改进到车载终端提供了一个完美的和稳定的技术支持。
1socket相关概念
Socket又叫“套接字”,是应用程序发出网络请求的一个借助点。socket,支持TCP / IP协议栈的基本操作单元,网络通信,这是一组复杂的隐藏在TCP/IP协议的背后的socket接口,一组简单的界面,对于用户来讲就是所有,只要跟指定的协议吻合,不用去计较UDP或TCP是通过何种方式让socket去组织数据的。
传输层协议栈有两个主要的协议,分别是TCP、UDP,两个应用程序里面,TCP负责传输功能,但是它在实现数据交换之前需要先建立TCP连接。UDP传递给应用程序数据发送IP层,但数据传输并不可靠,也不能保证他们能到达目的地。
2socket通信实现
一个IP地址和端口号确定了一个socket。因此IP地址和端口号在客户连接到服务器的过程中非常重要。连接过程中初始化服务器socket,绑定(bind)和端口监视器(listen),调用接受阻塞,在这个时候要等待客户端连接。在一个点客户端启动一个socket,然后将其连接到服务器(connect),一旦连接取得了成功,客户端和服务器之间就取得了连接。客户端发送数据,服务器收到一个请求(write)和处理请求(read),然后将数据发送到响应客户机的请求,客户端将数据进行读取,然后将连接关闭(close),交互就完成了。通信客户端和服务器之间的过程如图1。
图1建立socket通信的过程
2.1手机socket通信的实现
可以利用JAVA标准的API来实现Android手机中的socket通信,过程中需要注意一下几个问题:(1)中间的管道连接的InputStream/ OutputStream的流实现;(2)管道可以设置进行通信;(3)管道关闭就是socket关闭;(4)如果一个socket管道在创建过程中出现重复现象异常现象就会产生;(5)传播的整个过程中的秩序也是一个重要因素:最开始是由服务器得到输入流,接着服务器在将得到的这些信息传送到下面的客户端。
完成客户端和服务器的连接问题,先要设置连接端口,和访问服务器的IP,端口设置为1029,手机作为服务器的IP地址是不固定的,需要解析域名,使用安卓系统的手机客户端软件dyndns DDNS动态IP电话。需要DynDNS的官方网站注册用户名,申请一个免费的域名,在设置,输入用户名、密码和域的名称,然后单击开始解析,当ReportedIP返回一个IP,并返回到好的同时,表明,该领域已经成功解决了。动态IP电话将被发送到注册的域名,所以手机可以确定访问的域服务器。客户端和服务器通过IP地址,需要建立socket连接,所以需要域名转换成IP地址获得通过InetAddress.getByName IP:
InetAddress remotecontrol=InetAddress.getByName("");
System.out.println(remotecontrol);
解析出域名所对应的IP:/117.136.21.150。
IP的问题解决后,socket通信可以做到,当驾驶员android软件,点击“开始”按钮,接受连接请求,在同一时间启动汽车车载终端对应的二进制数据包传送到车载终端。发送数据格式定义在表1。
表1远程控制数据传输格式定义
包头 包长度 指令编号 设备编号 数据长度 数据正文
OX55 6Byte Ox01-0x08 0x01-0x02 1 byte 1 byte
包头包长度指令数设备号数据长度
OX55 6Byte Ox01-0x08 0x01-0x02 1 byte 1 byte
包头:ox55,一个字节;
包长度:发送数据包的长度,以字节为单位,占一个字节;
指令号:用于识别不同的数据,一个字节;
设备号:用于识别的遥控装置,一个字节;
数据长度:数据长度的文字,一个字节;
数据内容:8的二进制数据,传输。
车载终端接收的数据发送到移动电话包,根据解析出来的数据在表2.1中的数据的格式,然后身体的数据值,以确定驱动程序的命令。
2.2车载终端socket通信的实现
在本文中,设置车载终端的定时发送连接请求到手机,使用手机驱动程序,请单击“开始”命令车辆终端能够接受一个连接请求、手机和汽车终端建立连接,启动命令对应的数据应该发送到手机到车载终端、车载终端价值判断,基于意图的驾驶者和相应的输入输出端口操作。
socket通信车载终端通过GPRS模块,要用到AT+i命令,AT+i命令是由互联网解析和执行标准的AT命令扩展控制器。
3远程控制功能的实现
利用手机和车载终端建立一个socket连接,然后就能够达到远程控制的目标。这篇文章是要实现远程控制手机,汽车点火系统和空调系统的开关控制,实现对汽车的控制,并关闭发动机,空调的开启和关闭。
车载终端接收控制信号,控制IO口连接LED模拟点火系统和空调系统开关。在实践中,远程控制是通过车载终端的IO口控制继电器的开关来实现,从而控制LED的原理是一样的,只是不同的IO端口控制。
4总结
汽车车载电子在汽车电子研究的内容,是近年来研究的热点之一。本文介绍了汽车远程控制系统的设计思路和流程,使用socket通信方式,建立手机和车载终端。随着车联网技术的发展,下一步的研究方向可能就是针对车和监控中心以及车和车之间实现通信。随着汽车电子产业和无线网络技术的快速发展,不断提高,我们有理由相信,在不久的将来,完美的车载终端功能和技术将被用于每一辆汽车上,每个人都能感受到的车载终端给我们带来了极大的方便。
参考文献:
[1]刘国锦,刘新霞.基于S3C2410嵌入式车载定位系统设计[J].微计算机信息,2010.
关键词:TCP/IP协议;套接字;网络编程;Winsock
中图分类号:TP393文献标识码:A文章编号:1009-3044(2012)20-4819-04
On the Realization of Network Communication by Implementing WinSock in VC
GAO Ling-xia
(Chongqing College of Electronic Engineering, Department of Computer Science, Chongqing 401331,China)
Abstract: This paper describes the related concepts of Winsock, introduces the related technology of socket and programming principle of socket, analysis of network communication of connection-oriented socket programming model and connectionless socket programming model. In VC environment, development of network application methods and program code , Using Winsock to realize connection of ori ented network communication.
Key words: TCP/IP protocol; socket ; network programming; winsock
为了实现C/S模型的网络编程,90年代初,由Microsoft联合了其他几家公司共同制定了一套WINDOWS下的网络编程接口[1],即Windows Sockets规范,它不是一种网络协议,而是一套开放的、支持多种协议的Windows下的网络编程接口。Socket(套接字)实际在计算机中提供了一个通信端口,可以通过这个端口与任何一个具有Socket接口的计算机通信。应用程序在网络上传输,接收的信息都通过这个Socket接口来实现。现在Socket接口几乎是TCP/IP网络标准API,很多TCP/IP的网络应用程序都是基于Socket而编写的。
虽然现在有很多工具如Web浏览器、FTP程序可以在网络上传输数据和文件,但是通过WinSock编程有更大的灵活性,并且不需关心网络连接细节。
1 Client/Server (客户机/服务器)模型
在网络编程中最常用的方案便是Client/Server (客户机/服务器)模型[2]。在这种方案中客户应用程序向服务器程序请求服务。一个服务程序通常在一个众所周知的地址监听对服务的请求,也就是说,服务进程一直处于休眠状态,直到一个客户向这个服务的地址提出了连接请求。在这个时刻,服务程序被"惊醒"并且为客户提供服务-对客户的请求作出适当的反应。通信过程如图1所示。
2套接字
套接字是网络计算机与应用程序之间发送和接收数据方式的一种抽象描述[1]。用来实现主机和主机通信的一个接口,完成主机间的通信操作。它位于协议之上,屏蔽了底层的协议,能够实现各种类型的通信操作。它是网络通信中应用程序对应的进程和网络协议之间的接口。网络应用程序调用Winsock API函数实现相互之间的通信,同时,Winsock利用下层的网络通信协议和操作系统实现实际的通信,如图2所示。
图2应用进程使用Winsock进行通信
在网络中进行通信,至少需要一对套接字,其中一个运行于客户机端,称之为ClientSocket[3];另一个运行于服务器端,称之为Ser verSocket。套接字主要有三个参数,分别为通信的目的IP地址,使用的传输层协议(TCP或UDP)和使用的端口。根据这些参数,应用层就可以和传输层通过socket接口,实现数据传输。
2.1 Windows Sockets的相关技术分析
2.1.1 Windows Sockets的版本
常用的Windows Sockets有两个版本:WinSock 1.1网络编程接口和WinSock2.2网络编程接口。WinSock1.1由动态链接库WIN SOCK.DLL支持,主要应用在Windows95中,WinSock2.2由动态链接库WINSOCK32.DLL支持,主要应用在Windows98和Win dows2000中。WinSock2.2与低版本WinSock1.1相比,主要对一些协议进行了扩充,如IPX、NETBIOS等,同时对WinSock1.1的函数完成兼容。
2.1.2阻塞与非阻塞
套接字具备两种模式[4]:阻塞和非阻塞模式。当套接字处于阻塞模式时调用高模式的函数时,需要消耗一定的时间来等待操作的完成,而当套接字处于非阻塞模式时,调用函数立即返回,但通常会出错。当一特定的WinSock API函数指出一个错误发生时,需要获取对应的错误代码,根据WinSock版本的不同,包含在不同的头文件中。
关键词:JAVA;SWING;Socket;IM
中图分类号:TP319文献标识码:A文章编号文章编号:1672-7800(2013)012-0091-03
作者简介:徐华平(1977-),男,硕士,盐城师范学院讲师,研究方向为教育软件设计及教育信息化。
0引言
由于企业内管理、生产、销售等各个环节的信息流动与传递已成为企业正常生产与运转的重要条件,搭建一个基于企业内部网络的即时通信平台的重要性不言而喻。然而,通用的商业IM软件依赖于互联网接入技术,其信息安全性差。因此,有必要建立一种基于局域网的内部即时通信平台。
在各类网络客户端之间的通信机制的选择中,基于Socket机制无疑是成熟、可靠的选择。这种机制透明于各类局域网络类型,能够为企业提供一种优良、高效、快速的通信机制。基于上述优点,使得基于Socket机制的网络通信软件无需对企业现有的网络硬件设施进行任何变动,因而具有成本低廉的优点,能有效降低局域网通信负荷,提高局域网的使用效率,可以很好地解决企业内部局域网的各种通信需求。
1系统关键技术分析与选择
本文重点探讨即时通讯软件设计中实现系统通讯的关键技术。在应用系统中,客户端向服务端发送请求,等待服务器返回数据,再刷新客户端的数据,称之为通讯。在B/S或UE设备上实现即时通信的客户端,其同步方式是不可行的。此类客户端一方面处理能力弱,另一方面网络会引起延时,因此,在客户端之间以及客户端与服务器之间的同步协调难以做到,通常采用异步方式。在 C/S 网络编程中,数据的发送和接收通过Socket 套接口完成,套接字分为阻塞式和非阻塞式[1]。
通过对Java Net框架下GUI技术、通信协议等关键技术的分析,本通信器决定采用如下技术方案:
(1) Swing技术开发GUI桌面程序:采用Swing顶层容器、基本组件和事件处理等轻量级组件构建局域网通信系统的程序主要界面。
(2) UDP通信协议: 鉴于UDP协议无链接,不可靠传输,通信双方可不保持对方的状态,只需配置端口和IP地址即可通信,方便快捷,减少网络开销;考虑到UDP协议不可靠性,该通信器的通信协议中采用了确认与重传机制来保证数据传输的可靠性,采用了动态的超时重传定时器值提高了本协议的适应性和灵活性,还使用了在应用层对数据进行分片的方法来避免IP层分片的低效率[2]。
(3) 在本系统设计采用UDP通信协议时,基于UDP的Socket编程技术,中提供了两个类DatagramSoeket和DatagramPacket用来支持数据报通信。Datagramsocket用来在程序之间建立传送数据报的通信连接是数据报通信中的Socket。在数据报实现C/S通信程序时,无论在客户端还是服务器端,都要首先建立一个DatagramSoeket对象,用来表示数据报通信的端点,应用程序通过Socket接收或发送数据报。DatagramPaeket则用来表示一个数据报,它是传输数据的载体,封装了数据、数据长度、数据报地址等信息[3]。
(4)系统采用Derby作为数据库,Derby数据库是一个纯用Java实现的内存数据库,属于Apache的开源项目。因为是用Java实现的,所以可以在任何平台上运行。另外一个特点是体积小、免安装,只需要几个小Jar包就可以运行。
2系统总体目标与需求分析
2.1设计目标
(1)使用Swing组件实现图形化用户界面。
(2)使用Socket技术和UDP协议通过IP地址和PORT提供不可靠非连接通信。
(3) 实现基于线程池的多端口监听。
(4) 实现客户端间的文字、文件信息共享。
2.2功能需求分析
(1)用户管理。即时通讯系统拥有多个账户,允许多个用户注册。一个用户可以注册多个标识,注册所使用的帐号类型为字母数字的组合。注册新用户时必须填写符合要求的信息,注册后只有用户名与密码验证成功才能正确登录。
(2)分组管理。分组管理部分要能够实现分组的添加与删除,所添加的分组名称可以是中文也可以是字母数字的组合,通过对分组的有效管理便于更方便地管理好友。
(3)好友管理。用户可以查询所有用户,适当选择加为好友。一个用户可以添加多个用户为好友,同时一个用户也可以被多个用户添加为好友。用户可以删除好友,但是用户只可以将好友放在一个组中。
(4)即时通讯。即时通讯模块用户可以与在线的好友进行聊天,用户首先查看好友是否在线,如果在线即可进行即时通讯,并且用户可以查看与好友的所有聊天记录。
2.3数据库设计
根据数据逻辑结构设计的情况,本系统数据库的数据表共有好友数据表、用户表、分组表3个,和一般数据库应用系统基本类似,这里不再赘述。
3系统的设计与实现
(1)用户列表模块。
该模块实现本局域网内平台中当前登录用户的列表显示,并显示当前用户通过搜索或好友添加功能添加的用户。在每个用户节点上右击鼠标,会出现Popup功能菜单项,其中菜单项的添加好友和删除好友都会控制好友列表节点的增加和删除。关键代码部分如下:
……
add(p,BorderLayout.NORTH);
add(new JScrollPane(table),BorderLayout.CENTER);
setBounds(100,100,200,600);
setVisible(true);
validate();
thread.start();
模块说明:
本模块主要采用了Swing技术、多线程技术和循环技术。在系统进程启动时,利用多线程技术启动线程循环——自动检测数据库已有好友数据信息,然后使用Swing提供的JTree类对象生成一个分层显示数据的视图即用户列表。JTree类中的基本对象叫作结点,它表示在给定层次结构中的数据项。树以垂直方式显示数据,每行显示一个节点。每个树中只有一个根节点,其他节点从根节点引出。除根节点外,其他节点分为两类:一类是带子节点的分支节点;另一类是不带子节点的叶节点。树节点由Javax.swing.tree包中的接口TreeNode来定义的,该接口被DefaultMutableTreeNode类实现。为了创建一个树,使用DefaultMutableTreeNode类为树创建节点。
通过建立一个存放用户姓名的标签对象Lable,该标签显示的内容由用户在登录时在登陆界面输入的用户名信息来确定,另外创建一个标签来存放“在线列表”,然后实质上存放在线列表里面的内容则有一个表格组件来存放所对应的在线用户,通过UDP数据报广播来获取在线的用户的姓名以及IP地址,然后将数组的数据导入表格组件中,就可以形成在线用户列表。
(2)聊天功能模块。
用户通过单击在线用户列表中的节点选择某一用户头像,即可触发聊天对话框界面。聊天对话框的左上部分为显示聊天记录。左下方为聊天输入框。右侧可以显示对方的用户名和IP等信息。本次聊天内容在窗口关闭时,重新打开后仍会保存,一旦整个系统重启之后,上次的聊天内容才会清除。
关键代码如下:
……
con.add(new JScrollPane(inMessage),BorderLayout.CENTER);
con.add(p,BorderLayout.SOUTH);
Thread thread=new Thread(this);
……
模块说明:在用户聊天界面上分别创建一个既用于接收信息又用于发送信息的多行纯文本域对象JtextArea,它们来分别存放要发送的信息和聊天信息。outMessage用来存放所要发送的数据,而inMessage用来存放聊天的信息。
(3)用户搜索功能模块。
搜索在线用户的设计是基于广播数据报的,通过采用组播地址然后创建广播套接字,设置一个广播的范围,在这里设置的是一个本地的局域网的范围。设置了广播范围之后加入广播组,就可以广播数据报和接收广播数据报。
关键代码如下:
……
group=InetAddress.getByName("10.192.168.0");
socket=new MulticastSocket(port);
socket.setTimeToLive(255);
socket.joinGroup(group);
和多数通行通信软件一样,发送端在某一端口广播数据,接收端在指定的端口或端口范围内侦听并接收广播数据。
DatagramPacket packet=null;
byte data[]=total.getBytes();
packet=new DatagramPacket(data,data.length,group,port);
System.out.println(new String(data));
socket.send(packet);
……
这里的Packet是某一进程中待发送的数据报,定义一个数组用来存放,并且设置了长度length,还有端口号port,最后通过socket在本地的局域网上进行广播数据报。通过广播自己的IP地址,让所有在线的用户接收到自己的IP地址并且添加到对方的在线列表中,这样每一个用户的一个广播就使得列表可以更新。
(4)点对点资源共享功能模块。
如上所述,为了保证系统通信的即时性,选择的是使用UDP数据报的一个点对点的通信方式,实现了两个客户端间进程间的通信,这里使用DatagramPacket方法创建数据报对象:
DatagramPacket(b,b.length,address,8604);//发送端口是8604
DatagramSocket mail=new DatagramSocket();
通过DatagramPacket为存放指定数据的数据报,其中包括了指定的数据,数据接收方的信息,并且要明确发送的目的地址address,同时指定侦听该通信的主机端口号为8604。而在接收的时候:
byte b[]=new byte[5120];
mail.receive(pack);
构建一个长度为5 120字节的数组用于保存接收到的数据,同时设计了一个参数Pack,可以把收到的通信数据报传递给参数Pack。
4结语
本通信器界面友好, 虽然与大型复杂即时通讯软件相比在功能上还稍有欠缺, 但是其作为即时通讯的主体功能已经具备,尤其是其难易程度适中,综合运用了Java 面向对象的多种知识,是高等院校《网络编程》课程的一个很好的实例。
当然由于诸多条件的制约,以及系统设计的定位,该设计在文件传输多样化、网络适应性、通信机制、数据存储与共享方面仍然存在较多不足,主要有以下几个方面:
(1) 实现多样化文件传输,如:图片、文档、音频、视频等。
(2) 初期对系统所采用数据库的通用性认识不足,后期可以采用Mysql或XML等主流数据存储技术,使得系统具有更强的适应性。
(3) 改进系统通信协议,考虑穿透防火墙、异构网络实现多局域网之间的通信。
(4) 用户界面应借鉴主流IM软件,实现良好的用户体验。
(5) 如果作为一个高性能企业内部即时通信软件,应考虑到大用户、多并发的情况,应尽可能减轻服务器负荷,尽可能地将一些处理、判断放在客户端进行,节约服务器端开销。
参考文献参考文献:
[1]陈立浩. 基于B/S和C/S的即时通信系统[J].计算机工程, 2009(15).
关键词:winsock;TCP/IP协议;计费管理系统
Winsock是一个ActiveX控件,它为采用客户机/服务器通信机制的网络提供了编制接口,使客户机端和服务器端藉此实现连接和数据交换。它不是一种网络协议,而是一套开放的、支持多种协议的Windows下的网络编程接口。Socket实际在计算机中提供了一个通信端口,可以通过这个端口与任何一个具有Socket接口的计算机通信。应用程序在网络上传输,接收的信息都通过这个Socket接口来实现。
本文主要研究了Winsock的工作原理、编程方法,TCP/IP协议下计算机的工作原理,基于TCP/IP协议的网络编程,服务器端与客户机端程序的设计等,通过解决这些问题来实现Winsock网络按时收费系统的设计。
一、系统设计方案的研究
我们所设计的网络计费系统分为三部分,一是在win32平台上的线程对数据包的截获,并且进行初步的整理,生成日志文件,作为前台;而后台则是在windows net server上的数据库管理,直接取得第一部分截取程序生成的日志文件和通过ftp获取在Linux服务器上其它服务生成的日志文件,对其分析,并至于以BDE驱动的数据库文件中。三是计费信息用户查询子系统,使得用户能在线通过权限查询到自己各个时间段内的计费信息和费用情况,有利于减轻网络管理员的工作负担。
Socket有3种主要类型:流式套接口,数据报套接口和原始套接口。面向连接服务器处理的请求往往比较复杂,原理是:服务器端不断监听客户端的请求,当客户端向服务器端发出连接请求并被服务器端检测到以后,服务器会接收客户端的请求,并建立连接。本文在方案选择上采用了在网络编程中最常用的一种模型--客户机/服务器模型。选取了基于TCP/IP的客户机/服务器模型和面向连接的流式套接字。
二、系统的软件设计
(一)服务器的设计
①在初始化阶段调用WSAStartup(),此函数在应用程序中初始化Windows Sockets DLL ,只有此函数调用成功后,应用程序才可以再调用其他Windows Sockets DLL中的API函数。②建立Socket,初始化WinSock的动态连接库后,需要在服务器端建立一个监听的Socket,为此可以调用Socket()函数用来建立这个监听的Socket,并定义此Socket所使用的通信协议。③绑定端口,为服务器端定义的这个监听的Socket指定一个地址及端口(Port),这样客户端才知道待会要连接哪一个地址的哪个端口,为此我们要调用bind()函数,该函数调用成功返回0,否则返回SOCKET_ERROR。④监听,当服务器端的Socket对象绑定完成之后,服务器端必须建立一个监听的队列来接收客户端的连接请求。listen()函数使服务器端的Socket 进入监听状态,并设定可以建立的最大连接数。⑤服务器端接受客户端的连接请求,当Client提出连接请求时,Server端hwnd视窗会收到Winsock Stack送来我们自定义的一个消息,这时,我们可以分析lParam,然后调用相关的函数来处理此事件。⑥结束 socket 连接,这一过程可以由服务器或客户机的任一端启动,只要调用closesocket()就可以,而要关闭Server端监听状态的socket,同样也是利用此函数。
(二)客户机的设计
①建立客户端的Socket,客户端应用程序首先也是调用WSAStartup() 函数来与Winsock的动态连接库建立关系,然后同样调用socket() 来建立一个TCP或UDP socket(相同协定的 sockets 才能相通,TCP 对 TCP,UDP 对 UDP)。与服务器端的socket 不同的是,客户端的socket 可以调用 bind() 函数,由自己来指定IP地址及port号码;但是也可以不调用 bind(),而由 Winsock来自动设定IP地址及port号码。②提出连接申请,客户端的Socket使用connect()函数来提出与服务器端的Socket建立连接的申请,函数调用成功返回0,否则返回SOCKET_ERROR。
三、基于TCP/IP协议的网络编程
TCP/IP协议实际上就是在物理网上的一组完整的网络协议。其中TCP是提供传输层服务,而IP则是提供网络层服务。
TCP/IP协议的核心部分是传输层协议(TCP、UDP),网络层协议(IP)和物理接口层,这三层通常是在操作系统内核中实现,因此用户一般不涉及。编程时,编程界面有两种形式:一是由内核心直接提供的系统调用;二是使用以库函数方式提供的各种函数。前者为核内实现,后者为核外实现。用户服务要通过核外的应用程序才能实现,所以要使用套接字(socket)来实现。
四、系统测试包括测试仪器和软件调试测试仪器
Agilent网络测试仪表和AutoRunner自动化软件测试工具。软件调试:由于本系统要实现的功能比较多,所以在编写程序和调试时出现了许多问题,不过经过多次反复的调试后还是能把题目所要实现的功能都能实现了。
五、结束语
基于Winsock的编程,可以比较容易的实现按时收费系统的设计。利用Winsock编程的系统界面友好、操作简便、功能全面。这也就说明Winsock编程的优点,它将会成为软件开发的重要工具!
参考文献:
【关键词】I/O NIO BIO SOCKET通信 Java 多线程
1 引言
传统BIO技术在Socket通信中,系统需要为每一个链接建立一个线程去处理其请求,随着客户端的并发量不断增加后,会导致线程数量的增加严重影响系统的性能。由于并发量的增加有可能导致服务器宕机,严重影响到用户在使用过程中的良好体验。为解决传统BIO的不足,Java 中提供了新的API----NIO和NIO2来解决由于BIO技术带来的系统瓶颈问题。在NIO中系统不再为每一个用户请求注册一个线程,而是通过通道将每一个链接都注册到多路复用器上,通过多路复用器对注册在其上的链接进行轮询检查,发现有链接请求才会开启线程对其进行处理。NIO只在有连接请求时selector才会不断轮询检查通道IO操作是否完成,与NIO技术不同的是AIO技术是异非步阻塞的。AIO中不再需要多路复用器,而是由异步非阻塞通道直接操作read和write方法。在客户端读写请求发出后不再等待服务器的响应,而是处理完成后由操作系统来通知应用程序。AIO与NIO这两种技术都极大地改变了传统I/O流的不足。
2 Socket基本通信原理介绍
Socket是网络通信中的其中一方,用来接收网络通信中双方其中一方的请求,方便的对双方的数据进行传输。Socket通信分有连接的和无连接,面向连接的Socket通信与面向非连接的Socket通信相比有更高的可靠性和更有效的数据传输。本文基于有连接的套接字传输。
3 BIO、NIO、AIO技术比较
3.1 BIO技术简介
BIO技术同步并且阻塞,在这种情况下,服务器需要为每一个连接开启一个线程,只要有客户端有请求服务器就需要开启线程去进行处理。从客户端传来的每个请求,服务器都需要为其创建相应的线程去处理其请求。在BIO中,由于其线程的开销很大,适合于运用在并发量小的场景下。其基本模型如图1所示。
BIO网络通信基本步骤:
3.1.1 服务低端
(1)创建ServerSocket并绑定监听端口;
(2)创建Socket用来接收客户端请求;
(3)创建输入输出流用来接收客户端输入或向客户端输出数据;
(4)关闭输入输出流等系统资源。
3.1.2 客户端
(1)创建Socket绑定IP地址及端口;
(2)创建输入输出流用来接收服务器端相应或向服务器端发送数据;
(3)关闭输入输出流等系统资源。
3.2 NIO技术简介
NIO技术即New IO技术,NIO技术由很多类和组件构成,其最重要的由channel、Buffer、和Selectors三个核心部分组成。
Channel:Java NIO中的通道类似于流,但又不完全相同。既可以从通道中读取数据到Buffer也可以将数据从Buffer写入通道中。其中SocketChannel和ServerSocketChannel是NIO中提供的用来解决Socket通信中的服务器性能问题的。SocketChannel通过TCP协议来读取网络中的数据,ServerSocketChannel用来接收链接来的请求以供服务器相应。
Buffer:Buffer是用来为数据提供缓冲区的。在NIO技术中,所有的数据都必须经过缓冲区。缓冲区本质上为一块可读可写的内存块,NIO中提供了不同数据类型的缓冲区来处理不同的数据请求,和一些基本的方法来操作缓冲区中的数据。
Selector:Selector是单线程来处理多个链接请求的关键。在Socket通信中,如果将多个链接请求注册到多路复用器上,就可以用一个线程来处理多个链接请求,这样就提高了Socket通信的效率。NIO通信中的网络模型
如图2所示。
NIO通信基本步骤:
3.2.1 服务器端
(1)创建多路复用器Selector 用来选择通道;
(2)创建服务器端通道ServerSocketChannel;
(3)为多路复用器上注册ServerSocketChannel用来将数据通过通道读写;
(4)申请Buffer存储数据;
(5)多路选择器通过其key值轮询检查通道读写Buffer中的数据完成其通信过程。
3.2.2 客舳
(1)创建IP地址和端口号对应的SocketChannel ;
(2)将SocketChannel设置为非阻塞模式;
(3)创建多路复用器Selector注册SocketChannel到多路选择器;
(4)多路选择器轮询检查通道从Buffer中读写数据。
在NIO网络通信模型中,客户端向服务器端发起链接请求,客户端将数据写入服务器端Buffer中,然后通过channel来从Buffer读取数据或向Buffer写入数据,对于通道中的数据必须经过选择器来向服务器端的线程发起请求。而每一个多路选择器对应一个线程模型,这样一来,只有当链接请求有效时服务器才为客户端开启线程处理数据。对于同步阻塞的NIO模型中客户端在向服务器端发送完数据后会不断询问I/O操作是否就绪才能进行下一步的操作。此模型中由于不需要为每一个链接请求创建一个线程,大大减少了线程之间的切换带来的巨大开销。提高了I/O的效率,使得在socket网络通信更加高效。但由于NIO在链接请求中会不断询问I/O操作是否完成,其适合运用在短链接且并发量大的场合下。
3.3 AIO技术简介
AIO即为异步非阻塞IO,与NIO不同的是,在这种模式下,客户端发起一个链接请求后不在询问服务器端的I/O操作是否完成便立即返回。在使用过程中只需直接调用异步的read和write方法来读写数据,在读写过程完毕后由操作系统主动通知应用程序读写操作是否完成。由AIO的读写过程可以看出,因为在读写完成后客户端不需要再询问服务器端是完成了I/O操作,所以AIO非常适合于运用在那些并发量大且长连接的请求。AIO模型如图3所示。
AIO中有几个比较重要的类:
AsynchronousServerSocket:用来创建服务器端的ServerSocket并绑定地址监听端口。
AsynchronousSocketChannel:Socket在异步非阻塞通信中的应用,用来表示一个连接请求,并用来在通信过程中传递数据。
AsynchronousChannelGroup:异步通道的分组管理,目的是问了资源共享。创建AsynchronousChannelGroup时需要为其绑定一个线程执行器对象,这个线程池主要完成两个任务:处理I/O事件和派发CompletionHandler。在创建AsynchronousServerSocket时需要为其绑定一个AsynchronousChannelGroup。通过AsynchronousServerSocket创建的AsynchronousChannelGroup将属于同一组,共享其中资源。
CompletionHandler:用于定义在异步IO操作完成后的回调接口。
3.3.1 服务器端
(1)创建AsynchronousChannelGroup;
(2)创建AsynchronousServerSocketChannel并将它绑定在AsynchronousChannelGroup上;
(3)为AsynchronousServerSocketChannel对象绑定端口号;
(4)调用accept()接收客户端请求实现CompletionHandler接口调用读写方法进行读写数据。
3.3.2 客户端
(1)创建AsynchronousSocketChannel;
(2)绑定IP地址和端口号链接服务低端实现CompletionHandler接口中方法直接进行读写数据。
3.4 各种I/O技g比较分析
BIO:同步阻塞I/O,使用难度简单,可靠性低,适用于链接并发量小的架构且对服务器资源依赖更高。
NIO:同步非阻塞I/O,使用难度复杂,可靠性高,适用于并发量大且链接较短的场景。
AIO:异步非阻塞I/O,使用难度一般,可靠性高,适用于并发量大且链接长的场景。
4 结语
传统网络在IO处理方面存在着性能不足的问题,NIO与AIO包的引入解决了传统IO性能瓶颈问题,使的Java在网络通信中有了更搞得效率。对于不同的IO来说,它们各自有有不同的应用领域。对于那些并发量小,数据传输量小的场景来说,传统的BIO完全可以胜任其工作。相反对于那些对性能要求比较高,并发量大且对IO的要求比较搞得场合来说应该选择NIO或者BIO技术。如果客户端与服务器在长连接的情况下选择AIO相比NIO会更加高效一些。相反,如果是短连接的应用领域,则推荐使用NIO。
参考文献
[1]范宝德,马建生.Java非阻塞通讯研究[J].微计算机信息,2006,22(12-3):116-119.
[2]刘邦桂,李正凡.用Java实现流式Socket通讯[J].华东交通大学学报,2007,24(05):110-112.
[3]封玮,周世平.基于Java NIO的非阻塞通信的研究与实现[J].计算机系统应用,2004(09):32-35.
[5]任小强,陈金鹰,李文彬,胡波.网络通信之Java Socket多线程通信[J].信息通信,2015(06):206-207.
作者简介
王少辉(1992-),男,山西省平顺县人。硕士学位。现为山东大学(威海)机电与信息工程学院学生。主要研究方向为电路与系统。
陈晓鹏(1992-),男,天津市人。硕士学位。现为山东大学(威海)机电与信息工程学院学生。主要研究方向为电路与系统。
关键词:语音集群通信;移动网络;SSL Socket;opus
中图分类号:TP393 文献标识码:A 文章编号:1009-3044(2016)27-0014-04
Abstract: The paper analyzes the specific business demands and technical requirements of the industry users in the voice cluster communication, and gives a solution of voice cluster communication system for the mobile network environment. It designs the underlying transmission framework based on SSL Socket secure link and data transmission format, puts forward the basic method to establish interactive applications, according to the features of mobile network environment, it analyzes and uses the reasonable audio codec library, designs audio mixing algorithm, solves the core problem of the voice cluster communication system.
Key words: voice cluster communication; mobile network; SSL Socket; opus
随着公共网络服务和多媒体通信技术的发展,利用移动终端进行语音实时通信已成为民用市场或行业应用的热门业务[1]。相比较传统的电话语音业务,基于IP网络的语音通信系统具有跨地域、低成本、高质量、可定制等优势,且随着移动网络建设的不断升级,语音通信系统的通话效果和时延已与电话语音的差别不大。目前,市场上主流的语音通信应用有两类:一是采用频道、群组或聊天室形式的多人语音通信,如yy语音、qt语音等;二是采用一对一通话模式的IP网络电话,如Skype等。微信作为国内影响力较大的即时通信软件,也提供了一对一的实时语音功能。
对于满足专有行业或企业的语音集群通信业务[2],通常还需要考虑以下需求:1)群组通话是集群通信的主要业务模式,具有群组信道共享,避免通信互扰等服务要求;2)对于室外作业多采用移动网络,而非连接到有线网络共享的AP热点,网络质量受限。3)VPDN专网服务支持或其他网络安全要求;4)在语音业务基础上,提供文本通信、文件传输等定制功能;5)对语音、文本、共享文件等关键信息的私有存储或全业务存储。因此,在设计开发基于移动网络的语音集群通信系统时,应充分考虑行业应用特点,预留必要的业务应用接口。
1 基本传输框架
语音集群通信系统基于标准的客户端-服务器通信模型设计。客户端与服务器之间的数据传输采用TCP/UDP两种协议,分别适用不同的网络环境。当移动网络质量较好时,可以根据设置使音频数据通过TCP通道传输,保证通话语音的完整性和可靠性;当网络条件较差时,使用UDP通道传输可以避免TCP传输多次握手导致的网络拥塞,实现低延时传输,保证系统的可用性。语音通信过程中的控制信令和通信信令则是基于TCP协议可靠传输[3]。
1.1 构建安全通道
安全套接层(Secure Socket Layer,SSL)是Netscape公司研发的用于在IP网络上实现数据安全传输的专有协议,通过数据加密技术确保数据在网络传输过程中不会被截取及窃听。SSL及其后续发展的传输层安全(Transport Layer Security,TLS)提供了传输层的数据完整性保护,包括身份认证、协商加密算法、交换加密密钥等[4]。OpenSSL是互联网上适用性最广泛的SSL密码库之一,提供了多种编程语言的库支持。本系统引入OpenSSL 1.0.2方法库,将TCP Socket替换为SSL Socket,对传输层协议进行链路安全保护[5]。
SSL Socket的建立流程是:
1)客户端请求建立SSL Socket连接,并向服务器发送SSL版本、加密参数等必要信息。服务器返回自身的SSL版本、加密参数、安全证书等必要信息。客户端向服务器提供认证证书。
2)客户端验证服务器证书后,生成pre-master secret,并用公钥加密后发送给服务器。服务器对证书进行认证,通过后用私钥解密pre-master secret,并生成master secret。
3)通信双方通过master secret生成会话密钥,完成SSL Socket的创建,之后的通信数据将通过会话密钥加密传输。在本系统中,会话密钥采用TLSv1 AES256-SHA加密。
由于UDP是面向无连接的传输协议,为保证数据传输安全,在发送函数sendto()之前加入encrypt(),这里可采用与TLSv1 AES256-SHA强度相当的加密算法进行数据加密。接收侧在recvfrom()之后加入decrypt(),进行数据解密。
1.2 数据传输格式
本系统的数据报文格式如图1所示。客户端与服务器之间遵循此格式发送交互信息,其中报文头Ptrfix包含1个字节的类型信息,区别信令数据或语音数据,提供长度信息进行组包校验。载荷部分Data为实际交互数据,采用TLSv1 AES256-SHA或其他算法加密。由于UDP协议仅用于发送语音数据,其数据传输格式为图1的Payload部分,最大长度为UDP分片的理论最大长度65507B[6]。
2 应用流程
2.1 用户接入
本系统的接入流程如图2所示,主要包括:
1)建立连接:客户端向服务器请求建立用于控制信令和TCP数据通信的SSL Socket长连接。
2)版本确认:客户端与服务器相互发送版本信息,包括软件版本、操作系统版本、其他备注信息等,双方根据版本判断系统访问的兼容性。
3)用户登录:客户端向服务器发送登录认证信息,包括登录账户、登录密码,或是用于登录认证的证书信息。
4)密钥交换:该步骤为可选项,由于SSL Socket完成了TCP连接的密钥交换,如系统支持UDP传输,则需要服务器发送UDP加密的密钥信息给客户端。
5)群组信息:服务器向请求登录的客户端发送群组的状态信息,包括群组ID、名称、描述、拓扑关系,以及群组中用户的在线状况和当前状态。
6)用户信息:服务器向其他客户端发送新登录用户的状态信息,通知该用户已上线。
7)心跳信息:客户端完成基本登录流程,通过发送周期性的心跳报文,维持长连接状态。根据实际网络状况可调整心跳报文的发送周期,如部署地域的网络状态较好,可采用3至5秒的发送间隔。
2.2 信息响应
作为集群通信系统,信息响应的基本单位是群组。每个群组的数据处理和信息状态相对于其他群组保持独立,即群组之间的数据和资源是隔离的,这里通过建立用户信息的HashMap结构hmUsers和群组信息的HashMap结构hmGroups进行数据调用和处理。调用用户或群组对象时,需通过ReadWriteLock进行资源锁定,保护线程安全[7]。考虑到多线程存在资源切换和锁定的开销,在设计上主要对不同类型或分组的任务建立线程,如图3所示。其中:
1)接收线程主要响应网卡资源,监听服务端口,接收由客户端发送的业务数据或信令信息,如果是心跳消息,则直接返回响应;否则,将通过hmUsers和hmGourps查找所属群组,并将数据推送到指定群组的消息缓冲区中。
2)处理线程主要响应和实现具体业务。每个群组对象在实例化过程中都会创建本群组的处理线程和数据缓冲区,通过提取缓冲区中的数据并解析,线程将信令或其他业务数据交给业务响应函数处理,语音数据交给数据响应函数处理,并将处理后的数据发送给指定客户端。在处理线程中,可分模块响应语音业务以外的请求,对预留接口进行功能实现。
3)存储线程主要响应数据I/O操作。本系统对独占性的I/O操作采用单线程序列化处理,即所有群组的语音数据通过统一的缓冲序列顺序解码、混音和写入文件,降低线程切换的开销。为提高I/O读写效率,语音数据不会立即写入文件,而是积累时长2秒(可根据实际情况配置)的数据包后批量写入。
3 语音处理
3.1 音频编解码器选型
目前,国内4G LTE网络建设日趋完善,基于移动网络的语音通信技术已摆脱GSM时期小于16kbps的窄带传输限制。在音频编解码技术选型上,更多考虑的是适应16kbps到64kbps区间的高品质音频编解码算法。
本系统主要对Opus、Speex、AMR-WB和G.722.1四种编解码方案进行比较。Opus是在Skype的SILK编解码器和的CELT编解码器基础上发展的开源编解码方案,已形成RFC 6716标准,具有灵活的带宽适应性。Speex是基于CELP发展的音频编解码方案,但根据Speex官网提示,Opus的性能已在各方面优于Speex。AMR-WB(G.722.2)被广泛应用在WCDMA的话音业务上,其VBR特性可以较好的适应网络带宽变化。G.722.1提供了优于G.722的24kbps和32kbps音频编码压缩。
根据Opus-Codec给出的音频编码质量统计对比(图4),以及两份Google组织的主观评测报告[9][10],在同等比特率条件下,Opus编码能够达到或超过AMR-WB、G.722.1的编码质量。且考虑到国内各地区移动网络的传输质量差异较大,支持6kbps到510kbps比特率和VBR技术的Opus编解码器可为不同网络环境提供更稳定的语音通话效果。
3.2 Opus编解码实例
Opus是基于C语言编写的音频编解码器,Windows平台可直接加载Opus源代码进行函数调用,Android平台还需要对源代码进行NDK编译,生成供Java语言调用的so库。
使用Opus进行语音编码的代码片段如下:
OpusEncoder *opus_enc = opus_encoder_create(16000,1,OPUS_APPLICATION_VOIP, &err);
…
opus_encoder_ctl(opus_enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));
opus_encoder_ctl(opus_enc, OPUS_SET_BITRATE(24000));
opus_encoder_ctl(opus_enc, OPUS_SET_VBR(1));
opus_encoder_ctl(opus_enc, OPUS_SET_FORCE_CHANNELS(1));
opus_encoder_ctl(opus_enc, OPUS_SET_DTX(0));
…
while (total_length - input_pos > frame_bytes) { //仅处理采集片段,而非长期占用线程
…
get_data(input_buf, input_pos);
num = opus_encode(opus_enc, input_buf, frame_size, output_buf, max_output_size);
send_data(output_buf, num);
… }
…
opus_encoder_destroy(opus_enc);
3.3 混音流程
多路语音的数据混音是语音集群通信的核心功能。通过混音算法和调平参数,同一群组内的多路通话语音将根据逐帧数据的时间戳进行合帧处理,形成一路语音数据,送入声卡缓冲区进行放音。不论语音数据是以8位、16位或浮点形式存储,在多路混音时仅做逻辑叠加运算将会导致数据越界,必须先通过调平参数进行数据调整,之后根据叠加系数按比例缩减,保证合帧后的语音数据不会越界[11][12]。
混音操作的代码片段如下:
mixlocker.lock();
…
foreach(audio_source as, mixlist) {
source_buf = as.getbuf();
level = volume_level * generate_adjust(); // 设置调平参数
…
for (unsigned int i = 0; i < sample_num; i++)
mix_buf[i] += source_buf[i] * level;
… }
…
for (unsigned int i = 0; i < sample_num; i++) // 数据越界保护
mix_buf[i] = bound(mix_buf[i], -32768, 32767);
…
mixlocker.lock();
4 实验与分析
本系统分别在10M专线、联通4G、移动4G、电信4G等网络条件下进行测试,测试结果如表1所示。
在不同网络环境下,语音数据传输的平均延时在可接受范围,UDP丢包率小于2.2%,网络抖动小于20ms。通过主观测试,语音通话连贯,无连续丢帧,可懂性良好。因此,语音集群通信系统在传输延迟、网络抖动等方面可以较好满足语音集群和实时通信要求。在编码处理方面,优于国际电联G.711语音编码的90kbps带宽占用。
5 结束语
本文主要根据移动网络环境下的语音集群通信需求,给出一套可行的系统解决方案,并对其中底层链路、应用构建、核心编码处理等关键环节进行详细阐述。在实际应用过程中,不同领域的业务单位可能对系统的数据存储、用户负载、网络安全有更高的业务需求,可以通过合理配置磁盘阵列、负载均衡、安全网关、服务器等硬件设备或软件服务来实现。
参考文献:
[1] 2015年中国移动语音社交应用行业研究报告[R]. 上海: iResearch, 2015:19-23
[2] 王芳. 数字集群通信系统的构成及功能[J]. 电信网技术, 2005(2):9-12.
[3] Chauncey D, Kuliner M. Secure wireless communications system and related method: WO, US7987363[P]. 2011.
[4] 曾强. 网络安全协议SSL原理及应用[D]. 天津:天津大学, 2005.
[5] 秦贞虎. 基于OpenSSL开发的聊天工具的设计与实现[D]. 成都:电子科技大学, 2013.
[6] 李一鸣, 任勇毛, 李俊. 基于UDP的传输协议性能比较与分析[J]. 计算机应用研究, 2010, 27(10):3906-3910.
[7] 赵兴. 基于VoIP技术的无线语音通信系统设计[D].长沙: 湖南大学, 2011.
[8] opus-codec. Quality vs Bitrate[EB/OL]. http:///comparison/.
[9] opus-codec. Google listening tests[EB/OL]. http:///comparison/GoogleTest1.pdf.
[10] opus-codec. Google listening tests[EB/OL]. http:///comparison/GoogleTest2.pdf.
关键词:插件;socket;文件共享;接口;航天数据处理
中图分类号:TP311文献标识码:A文章编号:1009-3044(2011)01-0211-02
Application of Space Data Processing with Plug-in
CHEN Tuo, YAO Guo-qing
(Information Engineering, China University of Geosciences, Beijing, 100083, China)
Abstract:To find a solution of making space data processing software more reuseable,plug-in technology is used.This paper discusses three main means of communication in the plug-in area(Window Message, file sharing, socket). Finally, the decision of using socket to transfer data is made.
Key words: plug-in; socket; file sharing; interface; space data processing
1 概述
1.1 背景
随着航天技术的蓬勃发展,越来越多的应用都需要卫星数据的支持,与此同时,地面软件的数据处理软件也将受到前所未有的挑战。地面数据处理类型繁多(各种遥测参数,各种科学数据等等),使得软件的处理也越来越复杂。一方面,一些数据处理流程(如数据移位,同步头查找)已经较为成熟,重复实现浪费工时;同时,有些模块是需要重新设计,如界面显示,往往是因为载荷的变化而变化的,就算载荷没有变化,对参数的要求也不大相同。
1.2 插件技术
插件技术的引入,使得从开始的设计上将每项功能都最大化的独立,减少代码交叉,降低耦合,同时,使得开发相对独立,采取并行的方式进行软件开发,加快软件成型速度。在未来的开发应用中,如果有功能类似的需求,可以在原来基础上继承修改来适应新需求,大大提高代码的重用性,降低开发强度。
2 设计过程
2.1 特别的需求
常见的插件开发,多为单插件功能扩展,比如要了,时间不够,定义好接口后先实现了个简单的黑白显示插件,后来升级的时候换个彩色显示的插件,接口是没有变的,只是内部的数据处理显示,做了简单的插件升级。
区别于单个插件的功能扩展,这里还要解决的,是多个模块相互协作,插件与插件间也有了联系,甚至为了步调一致,插件与平台间也要进行通信,如何选择通信的方式成为接口设计之外一个非常需要考虑的问题。
2.2 接口设计
插件原理就是制定统一的接口,然后通过接口调用来实现功能的调用和扩展。在定义接口之前,应该先确定通信的方式,那么就三种常见的通信方式作下比较:
1)消息通信,由于插件与平台有直接相连的关系,插件间只能通过平台交互,好比内存与CPU的交互由主板来完成一样,由于应用中插件的变换比较多,同时之间的交互也并不特别复杂,可能只有几个消息,这种通过平台交互消息的方法似乎有待商榷。
2)文件共享,本例应用中,各模块间的交互,都被数据所驱动,如:数据接收模块接收到数据后便往下转发给数据处理模块,数据处理模块判断缓存中数据是否达到处理要求,如果一帧数据为128字节,那么达到256字节便开始往下处理。各个模块间由数据驱动倒是个不错的选择,不过与此同时,需要考虑文件互斥的问题,文件在这里属于临界资源,需要做好保护,以免程序出错。
3)socket通信,设计好文件格式后,都不用太多其它的处理,就是收到数据转发就可以了,对于数据的格式的多变性也能较容易的解决掉,设置一些格式的变量,再内部分类处理就可以了,处理弹性比较大,适用于多变的环境。
比较以上三种通信方式以后,对于本应用采用socket通信是最合适了,易于处理,又具有一定的弹性,适用于多变的格式需求。采用socket通信,又由于是本机通信,采用UDP就足够了,这里的UDP采用丢失重传机制,保证了本地通信的可靠性。那么把通信的接口抛开,除了必要的初始化和一些简单的控制,接口基本上可以定下来了,程序接口的定义如下:
Class PlugBase
{ PlugBase();
Private:
virtual BOOL CoInitialCfg()=0;//初始化自身
virtual BOOL CoRun()=0; //运行调用
virtual BOOL CoReset()=0; //重置控件
virtual BOOL CoGetInfor()=0;} //获得控件信息
接口函数不多,有初始化自身模块CoInitialCfg,运行调用CoRun,重置控件CoReset,以及提供给平台的获得控件信息的接口CoGetInfor。其中,初始化要用配置文件的方式给出,如组播地址,组播端口号,自身的ID号等等,这样方便应用时的修改,避免修改代码,反复的编译文件。
2.3 平台流程
平台如何获得这些dll信息呢,如何加载呢,隐式的加载太麻烦,每多了一个插件dll,平台的代码就要人为的添加新的头文件,再编译一次,相比之下,显示的加载要直接,避开了手动的添加文件,其优点就是不用修改平台就能直接加载使用。所以动态链接库的加载这里采用显式加载的方式,平台调用代码如下:
list BaseList;
PlugBase* pBase;
int (*pFunc)();
pFunc = (int (*)())GetProcAddr( LoadLibrary(path), "GetCoPtr"); //获得dll实例
pBase = (PlubBase*)(*pFunc)(); //取得对象指针
BaseList.pushback(pBase); //保存对象指针
这里是比较简略的写法,先声明一个基类指针列表对象,然后显式加载dll,获得dll中规定要实现的函数GetCoPtr地址,从而获得dll对象的指针。这里要说明的是,每个dll必须实现一个GetCoPtr的函数,返回值为实现了接口的对象指针。最后把指针保存下来。
其主要流程如图 1平台处理示意。
平台扫描指定文件夹,查看dll与匹配的配置文件,然后显式的加载动态链接库,并获得对象指针,扫描完成之后,调用对象的CoInitialCfg动作,初始化自身,按理说接下来就CoRun了,值得注意的是,有些时候,往往需要界面单元点击按钮来控制是否运行起来,也就是说其它插件的动作需要UI界面来调度,所以,注意主流程的右下方有两个已经完成的接口,一个是运行Run,一个是重置Reset,这两个实现是固化的,里面的代码默认的是所有控件的Run或Reset,这个事件由UI的dll来触发。
3 结束语
插件技术的引入,促使成熟有效的数据处理算法模块化,去除了代码修改干扰,加快了软件的开发速度,取得了一定的成果。同时,还存在一些问题,扩展性不够,平台功能不健全,譬如不能运行时加载删除插件,只能在平台初始化时加载,这些类似的工作,还需要在接下来的工作中细化解决。
参考文献:
[1] 潘爱民.COM原理与应用[M].北京:清华大学出版社,2000.
在《网络程序设计》中,套接字socket是非常重要的概念,教材上的解释是:套接字是两个通信通道上的端节点。看到这个解释,学生还是不能明白套接字的内涵。为了使学生更好地理解,通常采用如下比喻。既然套接字是作为通信的末端,那么可以使用“电话系统”与“邮局系统”这两个同学们熟悉的事物进行类比。可以把支持虚电路服务的信道看作电话线,套接字就类似于一个电话。同样,可以把提供数据报服务的通信看作邮局系统,套接字看作信箱。
(2)基于TCP套接字编程模型
面向连接的网络通信的建立有多个步骤,要使用多个函数。为了便于理解,可以将其比喻为“打电话”这个过程。要建立基于TCP的C-S(客户-服务器)通信,首先双方进程必须各自创建一个端点,也就是调用socket函数创建套接字,正如打电话之前,双方必须都拥有一台电话机一样。Socket是面向模型设计的,针对C-S通信双方提供不同的socket系统调用。客户随机申请一个socket号,这类似想打电话的人可以在任何一台入网的电话上呼叫。服务器拥有全局公认的socket,调用bind函数将套接字地址和所创建的套接字句柄联系起来,任何客户都可以向它发出连接请求和信息请求,这就类似于被呼叫方的电话号码告知了呼叫方。客户端调用connect函数发出连接请求,就好比拨打对方的电话。而服务端有可能在完成当前请求之前又发生多个服务请求,为了很好的处理这个问题,服务器调用listen函数将所有的服务请求放在一个请求队列中排队,并尽快处理这些请求[2],这就如被呼叫方在开启呼叫等待的功能,不错过任何呼叫请求。服务器端执行accept函数等待来自某一客户端的实际连接请求,实现与客户进程连接,这就如被呼叫方拿起电话,双方可以正式通话。最后,客户端与服务端完成数据传输后调用close函数关闭套接字,撤销连接。这就好比打电话双方通话结束后,挂掉电话。
(3)基于UDP的通信机制
用“邮局系统通信”来类比这一种通信机制是非常恰当的。基于UDP通信是面向非连接的,无法保证数据以正确的顺序到达。这就类似我们先后寄出两封信给对方,不能确保第一封信一定会比第二封信先到达对方手上。而在通信过程中,服务端和客户端双方首先都需要绑定IP地址和端口号,这就好比寄信之前,对方的通信地址我们是要已知的。而客户端发送信息以及服务端回应的时候,调用sendto函数来实现,需要指明对方的地址。这如同在寄信的时候,需在信封上要注明对方的地址信息。
(4)协议端口
在讲解“协议端口”时,学生总是不能理解为什么在网络通信的时候要指明端口号,为了解决这个问题,同样采取比喻教学法。大多数操作系统是支持多进程的,目的主机到底把收到的数据包送给哪个进程呢?就好比我们去银行办理业务,银行的业务有多种,有多个服务窗口。我们要成功地办理业务,必须知道对应的窗口号。同理,当你的主机开启多个服务时,如FTP、WWW、E-Mail多个服务,当接收到传送过来的数据包时,主机要准确的把数据包传送给相应的进程,这就需要数据传输的双方进程开启端口,这样数据包将会有标识有源端口,确保接收方顺利地将数据包传送至这个端口。
(5)带外数据
通常数据是按顺序传输的,然而套接字API概念性的提供了一些使用程序,从而可以使得一串数据无阻的先于普通的数据到达接收端。这就是所谓的发送带外数据。这就好比大家排队在银行依次办理业务,有个强盗拿着枪走入银行,越过整个队伍走到柜员面前。这个就可看作为带外数据。这个强盗能越过整个队伍,是因为枪标识他的特殊性,给了他凌驾于众人的权力。
(6)结语
关键词:局域网;即时通信;套接字;QT、TCP/IP
中图分类号:TP393.1 文献标识码:A 文章编号:1007-9599 (2012) 21-0000-02
1 系统概述
Qt局域网通信工具是Windows环境下的一款即时通信工具,与Windows下的飞鹆传书功能相似。该款工具可用于公司内部员工之间进行信息交换,如文件传输、信息广播、即时通信等功能,让员工可以通过公司内部网络实现自我管理,提高了整体运作效能。
本系统采用基于Socket的局域网通信工具的设计与实现的方法。基于Socket的局域网通信软件可以为企业原有的局域网提供一种良好,安全,快速的通信机制。它的实现无需对企业原有的局域网硬件进行任何改动,具有实现成本低廉的优点,它的使用能有效地降低局域网通信负荷,提高局域网的使用效率,可以很好地解决企业内部局域网的各种通信需求。
基于Socket的局域网聊天工具很好地诠释了Socket通信的原理,并且在企业内部通信、教学、讨论等应用中都具有一定的实用价值。它具有信息收发速度快,保密性好,占用网络带宽资源低,占用服务器吞吐能力低,易于编程实现等优点。
基于Socket的局域网通信软件应用范围广阔,不但可以处理传统的通信需求,而且也能扩展以适应新型的网络应用,如网络教育,数据影音传输等,拥有广泛的应用前景。
2 需求分析
聊天交流是目前互联网提供的主要内容。聊天系统有多种实现方式,类似ICQ属于一种点对点的聊天系统;还有一种是基于Socket的集中式聊天系统,这种聊天系统需要登陆统一的聊天服务器。在基于Socket的聊天系统中,主要有两种角色:服务器和客户端,不同的客户端登陆集中式的服务器,通过服务器将一个客户端发出的信息推送到其他所有客户端。基于Socket的聊天系统最早实现是使用网页刷新方式,通过客户端不断地自动刷新,服务器端整个页面内容下载到客户端显示,这种方式的聊天速度慢,而且有刷屏现象,很快被更新的聊天技术所替代。聊天系统在客户端和服务器之间主要传送的是文字信息,服务器端只需要把最近的文字信息推送到客户端,这样减少了网络传输内容,节省了网络传输的时间,无疑提高了聊天速度。这种“推”技术是目前基于Socket聊天系统的主要实现技术。
在基于Socket的聊天系统,客户端和服务器必须保持随时随地的连接。这有别于普通Web浏览的连接方式。在使用浏览器访问服务器时,先由客户端发出HTTP协议,然后服务器响应处理这个客户端的响应,再返回处理结果;请求(Request)和响应(Response)是一种一对一的前后因果关系。而在基于Socket的聊天系统中,客户端发出聊天信息的同时,客户端也在接受服务器发送过来的其他人的聊天信息,因此,请求和响应不存在那种前后对应关系,是两种分别独立进行的进程。因为服务器任何时候都可能发送信息到客户端,因此,客户端和服务器一旦建立连接,必须能让服务器在以后发送中寻找定位到这个连接。局域网聊天系统使该系统的用户能够通过客户端登入到该系统,然后直接与系统交互。
3 体系结构设计
通常的通信工具,都采用客户机/服务器(C/S)体系结构,C/S结构是这样的一种结构:它包括一个客户机(或前端),一个服务器(或称后端),客户机的作用是访问和处理远程服务器上的数据,服务器的作用是接收和处理客户机的数据请求。有时,可能有多个客户向同一个服务器同时请求服务,这就需要服务器决定怎样处理这些请求。Client/Server结构是当前数据库应用程序中极为流行的一种方式。尤其是网络技术的发展,使得当前很多系统都采用这种方式进行构造,其最大的优点是将计算机工作任务分别由客户端和服务器端来共同完成,这样有利于充分合理的利用系统资源。另外它的服务器端还可以将信息集中起来,任何客户机都可以通过访问服务器而获得所需的信息。Client/Server模型最终可归结为一种“请求/应答”关系。一个请求总是首先被客户发出,然后服务器总是被动地接收请求,返回客户需要的结果。在客户发出一个请求之前,服务进程一直处于休眠状态。一个客户提出请求后,服务进程被“唤醒”并且为客户提供服务,对客户的请求做出所需要的应答。
4 功能模块划分
4.1 其中主线程模块完成对网络的初始化,然后启动两个子线程:服务端监听线程以及网络扫描模块线程,然后由网络扫描模块得到当前的网络用户分布情况,并填充相关的数据结构,然后生成用户列表界面显示给用户。
4.2 通信模块又包括两个子模块:数据接收模块和数据发送模块,这两个模块都由系统定义的网络事件来触发。
4.3 输入/输出模块用来响应用户双击用户列表的某一项要准备发送信息时的消息,以及当系统接收到某个网络用户发送来的消息,要将其显示给用户的时候。
4.4 网络扫描模块是由主线程模块启动,进行网络扫描,确定哪些用户当前处于可到达状态,以及哪些可到达状态的用户安装有相应的通信软件,并启动之可以与之进行通信。
5 开发技术
5.1 WINDOWS SOCKETS网络编程接口
选定WINDOWS平台开发网络通信程序,可以选择WINDOWS的SOCKETS编程接口,Windows Sockets是一套开放的、支持多种协议的Windows下的网络编程接口。现在的Winsock已经基本上实现了与协议无关,你可以使用Winsock来调用多种协议的功能,但较常使用的是TCP/IP协议。Windows sockets无疑是我们进行网络编程的利器。所有的Windows Sockets实现都支持流套接口和数据报套接口。应用程序调用Windows Sockets的API实现相互之间的通讯。Windows Sockets又利用下层的网络通讯协议功能和操作系统调用实现实际的通讯工作。
5.2 TCP/IP协议、TCP协议
网际协议IP是TCP/IP的心脏,也是网络层中最重要的协议。TCP(Transmission Control Protocol,传输控制协议)是一种面对连接和数据流的可靠传输协议。它是许多高层应用协议的基础。TCP协议能为应用程序提供可靠的通信连接,使一台计算机发出的字节流无差错地发往网络上的其他计算机,因此对可靠性要求高的数据通信系统往往使用TCP协议传输数据,但在正式收发数据前,通信双方必须建立连接。
QT提供了QTcpSocket类和QTcpServer类用于编写TCP客户端和服务器应用程序。QTcpSocket类提供了TCP协议的通用接口,可以用来实现其他标准协议。
首先启动服务器,稍后的某个时刻启动客户端,它与此服务器经过三次握手后建立连接。此后的一段时间内,客户端向服务器发送一个请求,服务器处理这个请求,并且给客户端发回一个响应。这个过程一直持续下去,直到客户端给服务器发一个文件结束符,并关闭客户端连接,接着服务器也关闭服务端的连接,结束运行或等待一个新的客户端连接。
IP层接收由更低层(网络接口层例如以太网设备驱动程序)发来的数据包,并把该数据包发送到更高层---TCP或UDP层;相反,IP层也把从TCP或UDP层接收来的数据包传送到更低层。IP数据包是不可靠的,因为IP并没有做任何事情来确认数据包是按顺序发送的或者没有被破坏。IP数据包中含有发送它的主机的地址(源地址)和接收它的主机的地址(目的地址)。
如果IP数据包中有已经封好的TCP数据包,那么IP将把它们向‘上’传送到TCP层。TCP将包排序并进行错误检查,同时实现虚电路间的连接。TCP数据包中包括序号和确认,所以未按照顺序收到的包可以被排序,而损坏的包可以被重传。
UDP与TCP位于同一层,但对于数据包的顺序错误或重发。因此,UDP不被应用于那些使用虚电路的面向连接的服务,UDP主要用于那些面向查询---应答的服务.
TCP和UDP服务通常有一个客户/服务器的关系。两个系统间的多重连接是这样相互确认并协调一致的,TCP或UDP连接唯一地使用每个信息中的如下四项进行确认:
源IP地址 发送包的IP地址。
目的IP地址 接收包的IP地址。
源端口 源系统上的连接的端口。
目的端口 目的系统上的连接的端口。
端口是一个软件结构,被客户程序或服务进程用来发送和接收信息。一个端口对应一个16比特的数。服务进程通常使用一个固定的端口,因为在建立与特定的主机或服务的连接时,需要这些地址和目的地址进行通讯。
5.3 P2P
在P2P 系统中,每一个Peer 都是平等的参与者,承担服务使用者和服务提供者两个角色。资源的所有权和控制权被分散到网络的每一个节点中。服务使用者和服务提供者之间进行直接通信,可充分利用网络带宽,减少网络的拥塞状况,使得资源的有效利用率大大提高(包括各种计算资源和存储资源)。同时由于没有中央节点的集中控制,系统的伸缩性较强,也能避免单点故障,提高系统的容错性能。但由于P2P网络的分散性、自治性、动态性等特点,造成了某些情况下Peer的访问结果是不可预见的,例如,一个请求可能得不到任何应答消息的反馈。通常情况下图形用户界面应用程序是一个可执行线程,并且一次执行一个操作。如果用户在单线程的应用程序中从用户界面中调用一个耗时的操作,当这个操作被执行的时候,用户界面通常会冻结。当遇到这种问题时,就要考虑使用多线程了。
5.4 多线程编程
在一个多线程的QT程序中,这个图形用户界面在它自己的线程中运行,并且处理会发生在一个或多个其他线程中。这样做之后,即使处在比较强烈的处理中,应用程序也会响应图形用户界面。多线程的另外一个好处是在多处理器的机器中,不同的线程可以在不同的处理器中同步执行,这样可以获得更好的性能。多线程具有以下两点优势:
(1)可提高应用程序的响应速度。这对开发图形界面的程序尤其重要,当一个操作耗时很长时,整个系统都会等待这个操作。而使用多线程技术可将好耗时长的操作置于一个新的线程,从而避免上述问题。