1、本科生毕业论文(设计)题 目: 基于 C的短信收发系统的设计与实现 姓 名: 秦正阳 学 院: 数理信息与工程 专 业: 计算机科学与技术 班 级: 11级计算机4班 学 号: 1881110415 指导教师: 刘斌 职称: 副教授 2015 年 5 月 4 日安徽科技学院教务处制 目 录摘要1关键词1引言 11系统概述11.1研究系统的目的和意义11.2 国内外研究状况21.3 应用前景22系统知识简介22.1 GMS协议介绍22.2 TCP socket编程模式32.3多线程编程的介绍42.4开发工具53短息收发系统分析53.1 需求分析53.2 可行性分析53.2.1 技术可行性53.2
2、.2 经济可行性53.2.3 操作可行性64系统的设计和图分析64.1保存信息的内容64.2一级和二级服务器端64.3 client端64.4系统的总体设计75系统的实现和代码分析85.1一级server85.2二级server95.3 client端116.系统测试176.1 测试的目的及意义176.2一级服务器的性能测试176.3 二级服务器的性能测试186.4本系统测试的总结187 开发总结18致谢18参考文献19英文摘要20基于C的短信收发系统的设计与实现计算机科学与技术专业 秦正阳指导教师 刘 斌摘要:本短信收发系统是基于Linux下c语言,多线程,GMS短信协议,select非阻塞
3、方式,采用TCP的连接和传输方式和网络编程来实现的。我要做的就是模拟手机短息的形式来实现短信的收发,一个总服务器去管理多个二级服务去,然后二级服务器去管理多个客户端,通过设计二层服务器的形式来实现服务器的负载均衡,这样同号码段的号码就可以通过所在号码段的二级服务器实现客户端的短信的收发,不同号码段的信息要通过一级服务器进行转发实现客户端的信息收发,通过这个系统的实现可以把以前所学的知识联系起来,得到巩固和自己编程能力的提升。关键词:c/s;短信收发;多级服务器;负载均衡 ;多线程引言 随着现在网路技术的不断发展,出现了许许多多各式各样的聊天工具来拉近人与人之间的联系和加深人与人之间的关系。纵观
4、国内外的一些主流的聊天工具,他们大体的功能是非常相近的,主要是用来通讯的和格子有各自的优点和缺点。外国的主流社交软件有Facebook和MSN,中国也有许多这样的聊天工具,像腾讯推出的QQ和微信,主打的聊天和游戏互动中使用,这样可以加强玩家的互动和信息的实时交互来提高玩家的粘性,还有YY、微博、米聊等等国内主流的聊天软件。我首先借鉴他们设计这些聊天软件的一些思想和优点来应用到我的短信收发系统上,我的聊天系统设计了两层服务器,就和现在的手机上面的短信一样,它们分了不同的基带,一个地区会有一个基站管理本地区的号码,要是不同地区的号码进行通信的话会出现漫游,就和我们打电话一样会出现漫游费。我设计两层
5、服务器的优点就是可以降低服务器的负载,实现负载均衡。因为一个服务所连接的client数是是有限的,我的总服务器去管理二级服务器,然后二级服务器去分别管理自己号码段的client。一方面可以增加client的总数,分散负载,实现负载均衡;另一方可以挺高服务器的处理能力从而提高服务器的转发信息的效率。Client端可以实现已发信息的查找,未发信息的查找和收到信息的查找。运用在学校里所学的知识,来实现这个短信收发系统,得到知识的总结和自己编程能力的提升。1系统概述 1.1研究系统的目的和意义随着网络的普及,人类生活越来越依赖网络,人与人之间的交流也越多的在网络上进行。由于交流的实时性,即时通讯系统也
6、被越来越多的人所使用。即时通讯系统除了普通的生活上的交流,也在商业交流中越来越受到重视,它可以是个很好的与客户之间即时交流的平台,在时间上它要比电子邮件更加具有实时性,而费用相对电话交流也要经济的多。在这种环境下,聊天软件作为一种即时通讯工具,得到了很好的发展。因此,设计开发一个可以灵活用于网站,论坛,公司或企业内部交流的聊天工具很有必要。1.2 国内外研究状况随着网络的的发展,网络上出现了各式各样的聊天工具,有国外的也有国内的,但是他们的用途都一样,都是用来通信。纵观网络聊天工具的发展,市面上用的做多的莫过于QQ、MSN、YY、微信等聊天工具,这些聊天工具针对不同的人群有不同的选择,大多数的
7、人用QQ,微信进行聊天、发心情、写日志、发说说、图片等;工作上的人大多数使用MSN,这是国外的聊天工具,它不像QQ那样能够轻易得到别人的信息,从而带来骚扰,MSN必须使用邮件进行聊天,用它也显示其专业性;像YY这样的聊天工具,有玩游戏的在使用,有网络教学的在使用,群体不限,根据自己的爱好可以随意选取。还有基于网页的聊天工具,如新浪网聊天室、网易聊天室等。如新浪网聊天室,该网站为不同年龄、不同职业、不同地区、不同爱好的网友量身定制了数百个不同主题的“房间”。以新浪聊天室看,聊天室呈现积聚人气的作用,并开设不同主题的聊天室以使网名具有针对性的使用聊天室。针对不同年龄层开设的额“同龄话题”使各年龄层
8、次的用户话题和选择自己聊天对象群体,找到自己合适的聊天话题,并且针对目前社会流行的热门话题和流行话题都有相应的主题室。1.3 应用前景在网络发展日益成熟的今天,各式各样的网络聊天工具已经展现在我们的眼前。他们之间都是大同小异,实现的功能各不相同;有些聊天工具只是实现聊天通讯,传输文件等简单的功能,而有些聊天工具做的非常全面,还有这视频,语音,以及娱乐性的游戏等功能1。说到QQ,应该没有人不知道吧?它是腾讯出台的一款聊天工具,这也是在国内出现的比较早的聊天工具,历经十几年的发展,已经发展到几亿用户的规模。它实现的功能非常多,有语音、视频、文件、应用等功能。其最主要的就是应用功能,这些应用不仅给用
9、户带来了乐趣,而且也给自身带来了巨大的利润,腾讯在QQ的应用中添加广告、设置需购买的道具等来获取利益。价钱看似比较低,但是由于用户的基数庞大,每年的利润也非常高。这样的聊天工具在开发技术上已经没有什么难题,并且具有广泛的应用和市场空间。2系统知识简介2.1 GMS协议介绍应用了GMS协议的结构体中包含了信息当中许多重要的信息,如下面的结构体所介绍的信息,我也应用了GMS信息协议来填充自己数据结构,其中我的短信收发用到的数据就给其赋上自己需要的值2。存放信息的结构体,主要存放信息的发送时间,信息的长度和具体的信息。typedef struct datachar time30;/信息发送的时间in
10、t count;/信息的长度 char message160; /信息体 data; 发送信息的信息头部,存放一些重要的信息和进行信息验证的机制。typedef struct submit_headunsigned char sca_len;/短信息中心的地址长度unsigned char sca_type;/短信息中心号码类型unsigned char sca_add11;/短信息中心号码unsigned char file_tou; /文件头字节unsigned char pdu_type;/PDU类型unsigned char da_len;/接受方地址长度unsigned char d
11、a_type;/接受方地址类型unsigned char da_add11;/接受方地址unsigned char pid;/协议标示unsigned char dcs;/数据编码方案unsigned char vp;/信息有效期unsigned char udl;/用户数据长度submit_head;接收信息的信息头部,也是存放一些重要的信息。typedef struct deliver_headunsigned char sca_len;/服务中心的地址长度unsigned char sca_type;/服务中心类型unsigned char sca_add11;/服务中心地址unsign
12、ed char pdu_type;/PDU类型unsigned char oa_len;/发送方地址长度unsigned char oa_type;/发送方地址类型unsigned char oa_add11;/发送方地址unsigned char pid;/协议标志unsigned char dcs;/数据编码方案unsigned char stcs7;/服务中心时间戳unsigned char udl;/用户数据长度deliver_head;发送信息的一个完整的结构体。typedef struct submitsubmit_head sub_head;/发送协议头结构体变量data use
13、r_data; /用户数据结构体变量submit;接收信息的一个完整的结构体。typedef struct deliverdeliver_head delv_head;/接受结构体头变量data user_data; /用户数据结构体变量deliver;2.2 TCP socket编程模式TCP是一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信协议,由IETF的RFC793说明(specified)3。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,UDP是同一层内另一个重要的传输协议。TCP建立连接之后,通信双方都同时可以进行数据的
14、传输,其次,他是全双工的;在保证可靠性上,采用超时重传和捎带确认机制。如下图1基于TCP的客户/服务器模型的socket工作流程图4。TCP服务端: Socket() Bind() Listen() 客户端: Accept() Socket()一直阻塞客户端连接到达 Connect() 建立连接 (tcp三次握手) Send() Recv() 服务请求 Recv() 处理请求 Close() Send() 服务响应 Recv() 文件结束通知 Close() 图1基于TCP的客户/服务器模型的工作流程图2.3多线程编程的介绍对于一个程序来说我们可以把它分成若干个独立执行的执行流,我们把这种称之
15、为线程,线程可以提供多任务的处理能力5。在现在的大型编程中普遍使用多线程和多进程,应用多线程是为了更好的设计程序和编写和测试程序,这样一个线程来实现一个独立的功能,增加程序的可执行性。我们在使用多线程编程,要熟练的掌握线程之间的通信和同步等问题,还要了解每个线程的优先级,这样才能很好使用多线程来解决实际的问题。启动一个线程要用到pthread_create(&tid,NULL,pthread_func,NULL)函数来实现,tid是线程号,每个线程多有一个独立的线程号,pthread_func()是线程要调用的线程函数;在多线程的使用中要用到pthread_join()来等待要结束的线程,来确
16、保线程能顺利执行完成6。在多线程访问临界资源时,要使用到互斥所进行加锁,用到pthread_mutex_init()来初始化一个锁,pthread_mutex_lock()来对临界资源来进行加锁,pthread_nutex_unlock来对加锁的资源解锁,最后还要用到pthread_mutex_destory()来对锁的销毁和资源的释放。在访问临界资源时为了提高系统的处理效率要使用到条件锁和信号量来辅助完成,条件锁pthreah_cont_wait()7。2.4开发工具 (1)开发语言:本短信收发系统主要应用了C语言进行开发的,应用的是linux下C语言和脚本语言shell来共同完成的。其中主
17、要应用到的知识是Linux下的网络编程应用TCP进行连接的,采用了多线程的编程思想和最后用到脚本语言shell来对运行步骤进行优化。 (2)开发硬件平台:一部有redhat虚拟机的windows系统的个人pc。 (3)开发软件平台:Red hat enterprise linux 5, 编译器vim,调试器gdb,网络配置ifconfig,route等等。3短息收发系统分析 3.1 需求分析Client端需求,本短信收发系统是基于linux C来实现的,其中客户端的需求是:client端可以实现同号码段的client端进行通信,还可以和不同号码段的client进行通信。在发送信息是可以选择发送
18、和不发送,发送的保存在finish.txt里,不发送的保存在staff.txt里,接收到的信息保存在recv.txt里,并且client端还可以对这些信息进行查看。Sonsever需求,二级服务器需要可以实现同号码段client信息的转发,当收到不是自己号码段的client信息时,需要把信息转发给一级服务器,然后通过一级服务把信息转发给client所在的二级服务器,这样来实现不同号码段client端的信息之间的交互。Fatherserver需求,一级服务可以让多个不同号码段的二级服务器连接,来解决负载均衡,并且还要处理来自二级服务器的消息,转发给对应的二级服务器来实现信息的交互。3.2 可行性
19、分析 3.2.1 技术可行性 本系统是基于linux C语言下来实现短信的收发,其中主要应用到了网络编程TCP进行连接,还有GSM短信协议来实现短信的正确收发,当每连接一个client端时就启用一个线程来服务这个client,最后使用脚本shell来优化后面的运行步骤。3.2.2 经济可行性 经济可行性是对经济能力和投资能力,后期的维护运维费用的估算,对系统的经济效益进行估算,本短信收发系统是免费提供给用户的,因为市面上有不少收费的聊天软件,可以减少用户的使用费用来增加用户的使用黏性。3.2.3 操作可行性本系统在使用时需要在linux系统中开一个终端来连接自己号码所在的二级服务上,因为时间的
20、缘故并没有对界面进行优化,在操作上可能没有那么的简洁和方便。4系统的设计和图分析4.1保存信息的内容 Message体 message time number 图2信息体图 如图2所示是保存信息的结构体,信息中包含发送者的号码,发送的时间和短信的具体内容。4.2一级和二级服务器端 fatherserver一级: Sonserver3 Sonserver2 Sonserver1二级: 图3二级服务器模拟图 如图3所示是两个服务器的示意图(一级和二级server),一级服务器和二级服务之间采用的是TCP连接,TCP是面向连接的可靠的传输9,确保信息能够准确无误的传输给接收者,当每一个二级服务器连接
21、一级服务器时,一级服务器多会开辟一个线程去服务二级服务器,并且用数组存放二级服务器连接时返回的fd和二级服务器所代表的号码段,这可以确保信息所对应的的服务器并且能够让信息正确的转发。4.3 client端 client Client: 收信息 草稿箱 发信箱 功能: 图4客户端功能图如图4所示client所实现的功能,客户端连接二级服务器也是采用了TCP连接,和服务器的连接原理是一样的,客户可以实现信息的查询,可以查询收信箱,发信箱和草稿箱等功能。4.4系统的总体设计fatherserver N 转发 TCP连接 TCP连接 TCP连接 Sonserver1 Sonserver2是否在? Y
22、查询 TCP连接 转发 转发 Client1 Client2 Client3 信息 是否send? Y N 收信箱 发信箱 草稿箱 收信箱 图5系统工作流程图如图5所示是系统大致的框架和功能示意图。当client发送一个信息时就会提示是否发送,发送就会保存在发信箱中如果不发送就保存在草稿箱子中。Client把信息发给自己号码所在的二级服务器时,二级服务器就会检查要发送至的号码是否是自己管理的号码段,如果是自己就把信息转发给本号码段的client,如果不是自己号码段的client就把信息转发给一级服务器让一级服务器进行处理,一级服务器收到信息时就会检查信息的号码在哪个二级服务器所管理的号码段,然
23、后把信息转发给对应的二级服务器,最后二级服务器把信息转发给对应的client,当client端收到信息时就会打印出信息的内容并把信息保存在收信箱中。 5系统的实现和代码分析5.1一级server 图6一级服务器运行图如图6所示是一级服务器的运行结果。每连接一个二级服务器多会返回一个fd和它所对应的号码段,然后把这些数据保存在一个数组里面,供后面信息的匹配和查询。 client.fd = cfd;strcpy(client.num,buf);client.address = all_address;all_addressgeshu.fd = cfd;strcpy(all_addressgeshu
24、.num,buf);每连接一个二级服务器多会创建一个线程去服务它,并且要把连接上二级服务器数加1,和线程数匹配起来。send(cfd,hello sonser,13,0);pthread_create(&client.tid,NULL,fun,(void *)&client);geshu +;这是处理来自二级服务器的转发请求,通多号码段的匹配吧信息转发给对应的二级服务器上,实现信息的交互。for(i = 0;i geshu;i+)if(0 = strncmp(send_msg.delv_head.oa_add,client.addressi.num,3)send(client.addressi
25、.fd,&send_msg,sizeof(send_msg),0);5.2二级server 图7二级服务器运行图如图7所示,连接了两个来自130号码段的client端,分别是13011和13012client。二级服务器需要绑定两个socket进行通信,一个是和一级服务器进行通信,另一个是和client端进行通信。下面的就是绑定了服务的地址,实现和服务器进行信息的交互10。SPORT = atoi(argv2);strcpy(num,argv3);sfd = socket(AF_INET,SOCK_STREAM,0);if(-1 = sfd)printf(socket create failn
26、);close(myfd);return -1;下面的代码主要是绑定自己的地址用于和client端之间的通信,首先要确定协议类型AF_INET是TCP,然后绑定自己的端口号和IP地址,最后用ACCEPT()函数阻塞在那里等待着client端的连接,经过三次握手后就可以进行通信了。seraddr.sin_family = AF_INET;seraddr.sin_port = htons(SPORT);seraddr.sin_addr.s_addr = inet_addr(argv1);bzero(&(seraddr.sin_zero),8);SPORT = atoi(argv4);myfd =
27、socket(AF_INET,SOCK_STREAM,0);if(-1 = myfd)printf(socket create failn);return -1;myaddr.sin_family = AF_INET;myaddr.sin_port = htons(SPORT);myaddr.sin_addr.s_addr = inet_addr(argv1);bzero(&(myaddr.sin_zero),8);ssize = sinsize = sizeof(struct sockaddr);n = bind(myfd,(struct sockaddr *)&myaddr,ssize);
28、下面的代码主要是处理在同一号码段的client之间的信息来玩,通过前面保存他们fd和号码的数组进行号码的匹配来找到对应的client,然后把信息发送过去。当用户不在数组里的时候,信息就会自动的丢弃了,并提示找不到用户。if(0 = strncmp(num,send_msg.delv_head.oa_add,3)for(i = 0;i geshu; i +)if(0 = strcmp(one_cli.pclii.num,send_msg.delv_head.oa_add)char ss11;strcpy(ss,send_msg.delv_head.oa_add);strcpy(send_msg.
29、user_data.time,send_msg.user_data.time);strcpy(send_msg.user_data.message,send_msg.user_data.message);strcpy(send_msg.delv_head.oa_add,one_cli.num);send(one_cli.pclii.fd,&send_msg,sizeof(deliver),0);printf(n*send to %s clieant from %s client siccess*n,ss,send_msg.delv_head.oa_add);break;else if( i =
30、 geshu)printf(can not findn); 图8转化二级服务器运行图如图8所示的是所要转发的client不在本二级服务器的管理之内,需要把信息转发给一级服务器,然后通过一级服务器把信息转发给对应的二级服务器,最后二级服务器把信息转发给对应的client端。msg one_scli;strncpy(one_scli.num,send_msg.delv_head.oa_add,3);printf(n*zhuan fa to %s server *n,one_scli.num);send(sfd,&send_msg,sizeof(deliver),0);5.3 client端图9客户
31、端运行图如图9所示是client端登陆和发送信息的界面,其中可以实现信息的编辑和发送,在发送的时候会提示用户是否发送,发送的话就会保存在发信箱中,如果选择不发送的话就会保存在草稿箱。并且还提供信息的查询,可以查询收信箱,发信箱和草稿箱的信息。switch(choice)case 1:printf(*send message*n);memset(&send_msg,0,sizeof(submit);fflush(stdin);printf(please enter to num: );scanf(%s,cli_num);printf(please enter msg: );scanf(%s,cl
32、i_msg);printf(shi fou send (y/n): );scanf(%s,ch);if(strcmp(ch,y) = 0)submit_init(&send_msg,cli_num,cli_msg);send(cfd,&send_msg,sizeof(submit),0);finsh_save_(cli_num,cli_msg,argv5);printf(*send success*n);if(0 = strcmp(cli_msg,quit)break;else if(strcmp(ch,n) = 0)staff_save_(cli_num,cli_msg,argv6);pri
33、ntf(*message save*n);break;case 2:printf(n*receivemessage*nn);recv_print_(argv4);break;case 3:printf(n*finishmessage*nn);finsh_print_(argv5);break;case 4:printf(n*staffmessage*nn);staff_print_(argv6);break;case 5:return;default:continue; 图10客户端运行图如图10所示是在client端发送信息时提示用户是否发送信息,不发送的话系统就会调用staff_save_
34、(cli_num,cli_msg,argv6)函数把信息保存在草稿箱当中。 图11客户端接收信息图如图11所示是client端接收到信息,此时系统会申请空间来储存这些信息,其中调用deliver_print(&recv_msg)函数,把接收到的信息打印到终端上去,再调用函数recv_save_(&recv_msg,argv4)来吧接收到的信息保存到收信箱当中去,方便用户的查询和翻阅。MSG *buf = NULL;MSG *head = NULL;buf = (MSG *)malloc(sizeof(MSG);memset(&recv_msg,0,sizeof(deliver);n = rea
35、d(cfd,&recv_msg,sizeof(deliver);deliver_print(&recv_msg);recv_save_(&recv_msg,argv4);/buf = msg_tral(&recv_msg,buf);/head = msg_read();/head = msg_insert(head,buf);free(buf);buf = NULL;图12客户端发送信息图如图12所示是夸号码段发送信息的,是131号码段的client端,发送给130号码的client,它需要经过131二级服务器转发给一级服务器,然后一级服务器再把信息转发给130这个二级服务器,最后130这个二
36、级服务器把信息转发给130对应的客户端,这是信息转发的一个具体流程。13111client send()函数把信息发给131二级服务器。send(cfd,&send_msg,sizeof(submit),0);131二级服务器通过号码的匹配没有找到13011的client端,就把信息转发个一级服务器,让一级服务器处理。msg one_scli;strncpy(one_scli.num,send_msg.delv_head.oa_add,3);printf(n*zhuan fa to %s server *n,one_scli.num);/send(sfd,&one_scli,sizeof(ms
37、g),0);send(sfd,&send_msg,sizeof(deliver),0);一级服务器接收到信息就会进行匹配,然后找到13011client所在的130的二级服务器,然后就把信息转发给130这个二级服务器。memset(&send_msg,0,sizeof(send_msg);n = recv(client.fd,&send_msg,sizeof(send_msg),0);if(n = 0)printf(sonser %s exitn,client.num);return ;for(i = 0;i geshu;i+)if(0 = strncmp(send_msg.delv_head
38、.oa_add,client.addressi.num,3)send(client.addressi.fd,&send_msg,sizeof(send_msg),0);130二级服务器接收到一级服务器的信息时,就会通过号码的匹配吧信息发给13011这个客户端,实现了夸号码段转发。deliver send_msg;int i;n = recv(sfd,&send_msg,sizeof(deliver),0);for(i = 0;i geshu; i +)if(0 = strcmp(all_clii.num,send_msg.delv_head.oa_add)char ss11;strcpy(ss
39、,send_msg.delv_head.oa_add);strcpy(send_msg.user_data.time,send_msg.user_data.time);strcpy(send_msg.user_data.message,send_msg.user_data.message);strcpy(send_msg.delv_head.oa_add,send_msg.delv_head.sca_add);send(all_clii.fd,&send_msg,sizeof(deliver),0);printf(n*send to %s client from %s client sicce
40、ss*n,ss,send_msg.delv_head.oa_add);break; 图13收信息运行图如图13所示是查看收信箱的信息,其中调用了recv_print_(argv4)函数把储存在文件中的短信信息多打印在终端上,可以显示短信的发送者号码和发送时间和具体的短信内容。void recv_print_()int i = 0;int j;MESSAGE arr_msg100;FILE *fp = NULL;int leng;char chose;fp = fopen(./message/recv.txt,a+);if(NULL = fp)printf(open recv.txt fail !);return ;while
©2010-2024 宁波自信网络信息技术有限公司 版权所有
客服电话:4008-655-100 投诉/维权电话:4009-655-100