Socket在局域网聊天系统中的应用
2014-01-15李淑梅王志彬
李淑梅,王志彬
(吉林师范大学 计算机学院,吉林 四平 136000)
0 引言
Linux操作系统坚持以网络为核心为其设计思想,使其具有突出的网络性能,同时Linux具有多用户、多线程的能力,都为开发高性能的网络通信软件奠定了良好的基础[1-2].
在Linux操作系统中,实现网络通信主要采用的技术就是套接字socket(又称BSD socket).socket作为开放的网络编程接口,以其众多的优势广泛地应用在网络编程中.目前,大部分的局域网聊天系统都要求多用户同时在线,还要资源开销少、响应速度快的短信式交互,并且对数据可靠性要求不高,所以基于UDP 的socket成为开发网络通信软件的首选工具[3-4].
1 UDP socket编程
1.1 socket概述
在网络中,如果两台主机是通过“通道”进行通信,那么socket接口就是“通道”两端的出入口.socket接口为主机提供了一个通信端口,通过“通道”,可以与另一端具有socket接口的主机通信.如图1所示,网络上传输的信息,最终都是通过socket接口收发的.
socket的类型有SOCK_STREAM、SOCK_DGRAM和SOCK_RAW三种,用户使用的主要是前两种类型.SOCK_STREAM采用TCP协议,提供面向连接的、可靠的数据传输服务;SOCK_DGRAM采用UDP协议,提供无连接的、不可靠的数据传输服务.
图1 socket的地位
1.2 UDP协议及无连接服务
作为开放系统互联参考模型传输层上两个主要协议之一的UDP,为应用程序提供无连接服务.基于UDP的无连接服务,不必事先与对方建立连接,客户程序与服务程序之间的相互作用只需一个请求和一个应答就完成,因而数据传输的延迟极小;不需要维护发送双方的状态,可以同时支持更多的在线客户,使用更灵活;由于数据结构简单,UDP数据包的标题很短(只有8个字节),对资源的需求更少;由于没有拥塞控制的限制,吞吐量只受应用程序产生数据的速率、发送端主机的性能以及传输带宽的限制[5-6].
在局域网聊天系统中,拥有大量的客户,网络负担重,对响应速度要求高,同时网络数据大多为短消息,对数据安全性无特殊要求,使用UDP的无连接服务是有意义的.
1.3 UDP socket函数
在Linux 环境下,两个进程间进行通信,常用的标准库函数为[7-9]:
(1)socket ( ):使用此函数,为应用程序使用socket创建了一个socket号,同时参数中指定了通信所用的协议.
(2)bind():socket的客户端和服务端可以通过调用该函数来配置本地信息,将创建成功的socket号与本地地址和端口绑定,此时三元组{协议,本地地址,本地端口}确定,这是socket在全网唯一的标志.
(3)sendto( ):若源进程要发送数据,使用此函数,指定目的端的IP地址和端口,建立完整的相关,可以将缓冲区中的数据发送到指定的接收进程.
(4)recvfrom( ):若进程要接收信息,使用此函数,指定源端的IP地址和端口,可以将socket缓冲区中的数据接收.
(5)close():数据的收发工作全部完成,关闭socket时使用此函数.
在客户/服务器模式下,UDP socket编程的基本过程如图2所示[10].
图2 socket编程过程图
2 局域网聊天系统的设计
局域网聊天系统主要为局域网内的用户提供信息交流的平台,实现局域网内部通信的目的.作为局域网内的通信工具,采用客户/服务器体系结构,将系统分成服务器端和客户端进行开发.
聊天系统中不仅包括服务器与客户端的通信,还包括客户端与客户端的通信.由于每个客户都跟服务器建立了独立连接,客户端之间的通信(包括私聊和群聊),可以借助服务器完成.对于私聊,发送方A先将消息发给服务器,再由服务器把消息转发给接收方B;对于群聊,发送方A先将消息发给服务器,再由服务器把消息发给所有在线的客户.
2.1 聊天系统的功能
聊天系统的功能如图3所示:
图3 聊天系统功能模块图
服务器端主要包括初始化模块,监控模块和通信处理模块.初始化模块完成服务器端的公共套接字的创建与配置;监控模块监控当前在线用户,对客户的上线、离线进行处理,通过UDP的多播功能把客户名称等信息发送给客户端,生成客户列表显示给客户;通信处理模块主要对客户的消息进行处理,实现数据的发送与接收.如果服务器接收不到消息一直处于阻塞状态,直到收到消息.
客户端模块主要包括登录模块、刷新模块、聊天模块.登录模块完成用户的登录和初始化客户界面工作;刷新模块接收从服务器传来的信息,更新用户列表;聊天模块完成与单个客户的通信和向所有在线客户发送消息的功能.
2.2 主要执行过程
服务器端:服务器启动后,使用socket()创建公共socket号,用bind()与IP地址和端口绑定,等待客户的消息.一旦检测到客户登录成功,监控模块根据客户端的信息更新客户列表,并反馈给客户,使客户得知哪些客户在线.客户端就可以与服务器端进行数据交换,由通信处理模块完成聊天的功能,包括群聊和私聊[11].
客户端:首先调用连接模块检测服务器是否在运行,若运行再登录.客户端登录输入用户名,使用socket()创建socket号.用sendto()发送消息,以告知服务器在线,然后服务器返回在线用户列表.此时,可以进入聊天界面.用户选择单聊还是群聊,利用聊天模块,开始数据通信.若要结束,则使用close(),关闭socket.
2.3 部分源代码
局域网聊天系统采用C语言作为编程语言,下面是服务器端和客户端的部分源代码.
服务器端:
int main()
{
pub_sockfd = socket(AF_INET,SOCK_DGRAM,0);//服务器端创建数据报socket
if(pub_sockfd < 0)
{perror("socket error");
exit(1);
}
ser_addr.sin_family = AF_INET;//指定协议族为TCP/IP协议
ser_addr.sin_port = htons(PORT);//PORT为指定的端口
ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);// 指定本机IP地址
bind(pub_sockfd,(struct sockaddr *)&ser_addr,sizeof(ser_addr));//将socket与本地IP地址和端口绑定
……
}
客户端主要代码:
void client_sock( )
{
……
sockfd_client = socket(AF_INET,SOCK_DGRAM,0);//客户端创建数据报socket
……
cliaddr.sin_family = AF_INET;
cliaddr.sin_port = htons(PORT);// 设置服务器的端口
cliaddr.sin_addr.s_addr = inet_addr(SER_IP);// 指定服务器的IP地址
ret = sendto(sockfd_client,&cmd,sizeof(struct cli_send_cmd),0,(struct sockaddr *)&cliaddr,sizeof(cliaddr))//客户端向服务器端发送消息
……
ret = recvfrom(sockfd_client,buf,1024,0,(struct sockaddr *)&cliaddr,&cli_len);
/*接收从服务器端发来的消息*/
……
}
2.4 测试结果
图4为系统运行时私聊的界面.
图4 测试界面
3 结语
本文在Linux环境下,将基于数据报协议UDP的socket应用到局域网聊天系统中,使局域网聊天系统在减少资源开销的同时,加快了响应的速度,可以同时支持更多的用户在线.基于UDP的socket是收发信息的理想选择,其在网络中的应用值得进一步去探究.
[1]王继魁.Linux下基于shell脚本的聊天工具[J].吉林师范大学学报(自然科学版),2009,30(1):122~124.
[2]贾红伟,叶文来.嵌入式操作系统与嵌入式Linux[J].吉林师范大学学报(自然科学版),2005,26(3):97~99.
[3]周小松,朱雄军.基于UOP协议的Socket网络编程模式的实现[J].武汉职业技术学院学报,2007,6:84~86.
[4]陈健苇.基于Winsock的局域网聊天室设计与实现[J].数学技术与应用,2013,(2):134~136.
[5]吴培贤.Linux环境下基于UDP的socket编程浅析[J].网络安全技术与应用,2006,(1):63~66.
[6]杜经纬,王春红.在P2P网络环境下基于UDP协议穿越NAT研究[J].吉林师范大学学报(自然科学版),2012,33(1):93~95.
[7]朱 斌.Linux Socket编程及其在无线网关中的应用[J].微计算机信息,2007,23:70~74.
[8]邹 月,陈建兵.Socket 的网络编程研究与实现[J].电脑编程技巧与维护,2008,(1):11~12.
[9]周西峰,陆 鹏,郭前岗.利用Socket实现Windows与Linux平台间的网络通信[J].微型机与应用,2013,18:49~51.
[10]刘 烨.用Socket实现基于TCP和UPP的原理探索[J].电脑学习,2009,(6):6~7.
[11]萧泳东,肖 化.基于Linux的网络聊天系统设计[J].现代电子技术,2013,(3):51~54.