qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

IOS应用开发-数据库创建

一、前言
  数据库作为一种数据载体被我们频繁地使用。一般情况下我们会在程序的入口方法处完成数据库的创建。下面通过实例简单介绍两种创建数据库的方法。
  二、需求
  在documents目录下创建一个test.sqlite数据库,里面包含表User。User表含username和password两个varchar类型的字段。
  方法一:使用SQLiteManager创建数据库和表,并将创建好的数据库文件拖入项目中,最后调用以下代码将数据库复制到documents目录;
/**
*  将数据库文件复制进沙盒
*/
-(void)createEditableCopyOfDatabaseIfNeeded
{
// 先判断 sandbox 下面的 documents 子文件夹里面有没有数据库文件 test.sqlite
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"test.sqlite"];
BOOL ifFind = [fileManager fileExistsAtPath:writableDBPath];
if (ifFind)
{
// NSLog(@"数据库已存在");
return;
}
else{
NSLog(@"数据库不存在,需要复制");
}
// 如果不存在数据库文件,则复制数据库文件
NSString *defaultDBPath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"sqlite"];
BOOL ifSuccess = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!ifSuccess) {
NSLog(@"Failed to create writable database file with message '%@'.", [error localizedDescription]);
}else {
NSLog(@"createEditableCopyOfDatabaseIfNeeded 初始化成功");
}
return;
}
  方法二:利用开源的FMDB库代码创建数据库;
/**
*  代码创建数据库
*/
- (void)createDatabaseIfNeeded
{
// 数据库路径
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *doc = [paths objectAtIndex:0];
NSString *path = [doc stringByAppendingPathComponent:@"test.sqlite"];
NSFileManager * fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:path] == NO) {
// create it
FMDatabase * db = [FMDatabase databaseWithPath:path];
if ([db open]) {
// 建立User表
NSMutableString *sql = [NSMutableString stringWithFormat:@"%@",@"CREATE TABLE User"];
[sql appendString:@"("];
[sql appendString:@"username varchar,"];
[sql appendString:@"password varchar"];
[sql appendString:@")"];
BOOL res = [db executeUpdate:sql];
if (!res) {
debugLog(@"error when creating table User");
} else {
debugLog(@"succ to creating table User");
}
[db close];
}
else {
debugLog(@"error when open db");
}
}
}
  注:FMDB库使用教程http://blog.devtang.com/blog/2012/04/22/use-fmdb/
  三、总结
  1、第一种方法创建数据库在需求变动的情况下(如增加几张表)容错率稍高,推荐使用第一种方法;
  2、两种方法均是先判断数据库是否存在然后再决定要不要创建/复制数据库。在一种特殊情况下-应用更新版本,其实原来的数据库文件是会从老的版本中拷贝到新版本中(参考:http://blog.csdn.net/zyx586/article/details/18989199),所以更新版本后数据库文件是不会做任何改变的,就算你在新的版本中完全改变数据库的结构。所以如果存在数据库变动的需要在应用版本升级后重新创建一个全新的数据库并备份旧的数据;

posted @ 2014-02-19 11:21 顺其自然EVO 阅读(1371) | 评论 (0)编辑 收藏

软件工程之软件质量管理

  软件质量管理主要是为了确保工程项目按照设计者规定的要求满意的完成,软件质量管理在软件工程中有着重要的作用,无论我们的代码写的如何巧妙,还是使用了多么先进的技术,在软件质量管理面前,这些都是小巫见大巫。
  在软件质量管理中有八个黄金法则,分别是:
  A.始终从用户角度出发
  B.领导能力
  C.团队成员主动参与性
  D.流程方法
  E.系统方法管理
  F.连续的改进
  J.决策中的事实说话
  H.互惠互利
  接下来,我们就来看看,软件管理这一章的总体内容概述:
  对整章的内容有了一个感情上的认知,接下来,在我们一一了解各个知识点之前,我们先来看一下,软件质量设计流程图:
  对软件质量设计的过程有了一个大概的了解,知道软件设计的过程具体是怎么一回事,不至于盲目开端,做到事半功倍,接下来,我们再来了解一下,软件质量的相关概念以及模型:
  了解了基本的概念与模型,对基础知识有了整体的感知,做好软件质量固然重要,但是软件质量如何得到保证,让用户用的舒心,放心,这也是一门很深的学问,接下来,我们就来看一下软件质量保证的相关知识:


 软件的质量有了一定的保证,对于用户来说无疑是一份保险,软件的质量得到了保证,接下来我们再来了解一下,软件的可靠性:
  接下来,我们再来看我们最后一个小知识点,软件配置管理:
  总的来说,软件的配置管理就是管理软件在整个生存周期中的千变万化,软件质量管理是企业的无形资产,就如同服务一样,对企业的发展有着重要的作用。让我们做好软件质量管理的工作,进而促使我们的软件在质量管理中越来越好,越来越茁壮......

posted @ 2014-02-19 11:10 顺其自然EVO 阅读(267) | 评论 (0)编辑 收藏

Loadrunner多服务器连接问题

今天用想增加一个压力机,在服务器管理列表里怎么也连不上,后来解决方法如下:
  1. 关闭所有loadrunner组件,并手动结束lr_开头的进程
  2.找到惠普loadrunner安装目录(C:\Program Files\HP\LoadRunner\bin),手动运行magentproc.exe即可

posted @ 2014-02-19 10:57 顺其自然EVO 阅读(261) | 评论 (0)编辑 收藏

JIRA管理思路

 刚刚开始用Jira的时候,只是觉得这是一个方便的bug管理系统,可以将在测试过程中所发现的bug录入、分配给开发人员。
  之后开始在公司内使用,之前也曾经想尝试使用bugzilla。在D的建议之下,又因我用过Jira,因此一拍即合,开始使用了。
  因起初只是使用者,因而并未有站在一个管理者的角度上来看JIRA在项目管理中的作用和意义。因此今日再看时,已发现由于出发角度的错误而出现的很多偏差,导致的此时的问题。
  没办法有效的管理bug,没办法有效的让所有人及时添加bug,没办法让所有人方便看到当前有哪些bug。因为太乱了,模块划分乱、版本划分乱、处理者乱,处理流程乱。
  当这些问题出现后,才发现之前的错误。这些为什么没有在开始使用时就理解和计划实施呢!
  现在来看JIRA,这是一个项目管理的很好辅助工具,将所有项目开发、运作过程中的所有task 、 bug、创意、改善意见都可以融汇进入这个系统。可以在第一时间将这些问题指派而责任人进行处理。
  而想用JIRA来做好BUG管理和项目管理,有这几个重点要做好!
  1.定义模块
  模块反应了问题出现因素的范围。所发现的问题、所需要进行的任务、改善意见的指向、创意所应用的范围。
  2.定义里程碑
  问题、任务、意见、创意都需要分配在某一时段进行处理,时段可以是时间为单位的,周、日、时、分,也可以是里程碑,alpha/beta/close beta/open beta。如果所有的事情都可以以这两种单位计量的非常清晰,那么首先可以称赞的一点是,你的负责心已经体现出来了,你知道在什么时间该做什么事,同时,你让你的战友们知道,他们应该在什么时候做什么事!
  3.定义全局处理流程
  第1点和第2点,是你在为这个项目管理做的基础准备,有了第1点和第2点,那说明你在其中的工作,但这并不表明这个系统就可以运作起来。要运作起来,就必须你和你的战友们都可以在处理JIRA上的所有事务时的处理流程。
  建立:建立一个issue。什么样的东西应该建立在JIRA中,我得到的经验是,所有的工作任务、所有的bug(开发过程中的,A与B之前的,A与C之前的,B与C之前,所有、所有),不单是测试小组所发现的一些黑盒测试的bug,开发过程中的也不遗漏。这样,你可以看到这个项目在动的,每天所有人都在发现问题,解决问题。
  分配:问题要给能解决问题的人,问题要给理解这个问题的人。程序上问题你给了一个商备人员,那你不对了;程序的问题你给了程序,可以程序不明白你说的是什么,那也是你不对了。要降低沟通过程中的风险,建立问题者,想清楚,这个问题要由谁来处理,要告诉他什么信息。你在没有告诉清楚这些信息的时候,你对这个问题还是最大责任者。
  开始:开始是指接收到这个issue后的处理手段之一,因为还有拒绝这种可能。开始处理这个问题,在向所有人声明一件事情,这个问题我开始着手处理了,我会按着计划和需求来完成这个事务。那么,开始做这件事的人,你要很坦诚的向自己说,我知道这个事务是什么,我知道要怎么去处理,我知道要在这个时间内怎么处理。你开始接受这项事务,是你对于分配给你这个事务的人的一个回应。这时事务的责任在你的身上。用你的职业精神来处理这个事务吧。
  解决:整个的处理过程统称为解决。虽然有可能出现解决不了、或者在解决的过程中需要其它人来帮忙,也可能需要很多的讨论和会议,这都是解决的过程,在这个过程中,把你做过的事情,对于这个Issue相关的资料,信息版本,记录下来。让别人知道,你是用什么方法来解决的,你这种解决方法是不是很安全,还有没有其它更优化的方法。
  关闭:解决完一个事务后,通常这种事务的责任转移到分配人的头上,分配人要处理的事情是,这个事务是否如需求、计划所完成,完成质量是否符合要求。在通过验证后,这一个问题需要你的关闭。在出现不符合的情况,你不能关闭这个issue,你要提供更多信息,更多资料,方便他再来解决。
  重开:对于bug,出现重现的情况是常见的,这时不要让JIRA上有更多的垃圾信息,也方便开发人员找到问题原因,你需要重开这个bug,并附上相关的信息。
  4.每日的统计与清理
  管理项目要盯,每日的盯是少不了的,看全局的issue数量、关闭情况、进行情况、所剩未解决的数量。你可以有的放矢的去针对这些问题来看。也可以看到,谁的问题比较多,谁的进度比较慢。因为什么问题将影响进度,因为什么问题将影响产品品质。
  你也有责任要清理一些问题,这种情况出现在,你没有让所有战友都可以很好的使用这个系统。清理的另一意义是理,有一些问题,你可能要在这一阶段放弃,那需要理到某一个其它时段,这个问题需要换由其它人再进行继续的处理等等。
  5.阶段的统计与整理
  阶段,这么划分吧,每周3/2这样两个阶段,这是除了第4点所说的之外的最小阶段吧。以它就是周、版本计划阶段、版本大的阶段划分这样的划分情况。
  通过阶段内的完成情况,你可以看到谁处理的问题太多了,谁少一些,谁的难度高一些、谁的能力不足、谁不负责任。哪个部门做得不足,哪一模块需要更多人帮忙。如果说日为单位是盯的话,那么阶段来统计与整理,就是盯之后的分析与解决方案。
  6.最大力度的使用过滤器
  Jira提供了较多的查询条件可供个人创建过滤器和与团队分享过滤器。同时还可以自定义自己的主页,相信自定义主页这个功能在google上你已经感受过了。同样这些过滤器可以变为你的主页中的一部分,把你最需要关注的issue都呈现在你每日的第一位置。
  JIRA,是一个工具,是改变你原始管理思维的一个突破。如果你要用的话,请记住,Jira不是你一个人会用就行了,是一个团队、一个系统。否则他运转不起来,就算转起来了,也有出现更大问题的时候。
  现在我面对的就是出现这个大问题的时候。希望通过这样的一处整理思路的过程,让公司的JIRA系统可以快速恢复起他应有的作用。

posted @ 2014-02-19 10:56 顺其自然EVO 阅读(224) | 评论 (0)编辑 收藏

Web自动化测试之困

 标题借用《web之困》这本书名,借机吐槽一下在web自动化测试中遇到的各种不顺畅。看了这本书,大感欣慰,因为终于有专家说出了我多年想说而不好意思说的话——现在的web应用就是建立在一堆胡乱拼凑的技术基础之上的。
  从底层协议级就定义不周到渲染技术的五花八门;从古老的html、css、java applet、ActiveX到javascript、flash、sliverlight、html5;从浏览器的各显神通到眼花缭乱的版本升级;从静态到动态;从即时到异步,真是一个百家争鸣、百花齐放啊。虽说给普通用户带来了赏心悦目的享受,可真苦了我们这些测试工程师了。手工做浏览器兼容性测试都不是一般的麻烦,更别提自动化了。十几年前我每样技术都尝试去学习,后来发现我学的速度还赶不上技术新出的速度,于是我厌倦了,从此对web前端技术及其排斥。我幻想着某一天前端技术可以统一得象操作系统那样规矩和稳定。不过看来一时半会还实现不了,所以厌倦归厌倦,活还是要干的,所以几年来我也在考虑这是非做不可的。于是前一篇提到的vs2010就是一个尝试。当时考虑操作系统是ms家的、浏览器是ms家的、自动化工具是ms家的甚至C#语言也是ms家的,要是这样还不顺利,恐怕别的工具更别指望了。事实上,我还是低估了事情的复杂性。
  录制/回放遇到的麻烦随便列举一下就有这些:
  只支持ie,且不能使用64位版本
  视图缩放比例要求必须为100%
  不能识别flash插件
  各种意外(如窗口没有在最前端、没有最大化等、控件被阻止运行……)导致回放中断
  建立自动化任务时不能在后台运行(因为要在桌面环境真实启动浏览器),所以管理员必须登录。这样一来,服务器一旦重启就无法做到无人值守的继续运行
  ……
  诸如此类,总之想顺利走通一段自动化脚本可费劲了,经常是烦不胜烦
  为此我还总结出一堆录制脚本的经验,比如:
  把场景分割成每段尽量少操作的多个脚本文件
  尽量用键盘操作,少用鼠标操作
  屏幕上尽量少留无关窗口
  对于浏览器,尽量在同一个页签中操作,尽量避免弹出窗口造成主流程被干扰
  动作、脚本之间留的延时要足够,比如连续执行两条sql,就有可能第二条执行出错
  ……
  但真要把这些问题都注意到了,费的心还不如手工来一遍算了。再说费这么大事只是为了回归验证以前的功能,确实有点得不偿失。所以过后反思起来有这样一些教训:
  1.目标定位有偏差。借鉴自Apple Chow观点:只保留少数几个用来验证端到端的集成场景的高级别冒烟测试,除此之外尽可能编写底层的测试。
  2.工具不给力。当然如果有google的水平,自行探索和开发各式各样的测试工具和框架那自然是厉害了,但是没这水平啊,还是只能找现有的工具用。
  后续准备尝试selenium。说到这里,就想起有的团队成员提出经常换工具的困扰。——这个问题应该这样看:使用工具是为了解决问题,是人的思想和能力去驾驭工具而不能让工具限制了人的思想和能力。所以要去掌握事物的本质,那么换工具也会是经常和顺理成章的事情。

posted @ 2014-02-19 10:42 顺其自然EVO 阅读(300) | 评论 (0)编辑 收藏

对web项目的单元测试方法

 1、HttpClient模拟请求,需要打开服务器
/*
Map<String,String>param=newHashMap<String,String>();
param.put("businesstype","1006");
param.put("trade_no","123123123");
param.put("orderid","123456");
GetMethodmethod=getMethod(URL,param);
client.executeMethod(method);
if(method.getStatusCode()!=200){
fail("未正确响应");
return;
}
Stringresponse=method.getResponseBodyAsString();
System.err.println(response);
PayStatusResponsepayStatus=newPayStatusResponse();
payStatus.setBusinessType(1006);
payStatus.setOrderId("");
payStatus.setResultStatus(1);
StringpayStatusJson=JsonUtil.toJson(payStatus);
System.err.println(payStatusJson);
assertEquals(payStatusJson,response);
*/
    json和对象之间转换用jackson框架
  2、springmvc可以使用mockMvc
  staticimports:
MockMvcBuilders.*,MockMvcRequestBuilders.*,MockMvcResultMatchers.*
WebApplicationContextwac=...;
MockMvcmockMvc=webAppContextSetup(wac).configureWarRootDir("src/main/webapp",false).build()
mockMvc.perform(get("/form"))
.andExpect(status().isOk())
.andExpect(content().mimeType("text/html"))
.andExpect(forwardedUrl("/WEB-INF/layouts/main.jsp"));

posted @ 2014-02-19 10:35 顺其自然EVO 阅读(657) | 评论 (0)编辑 收藏

测试用例的编写格式

 一、step by step(按步骤)
  step-by-step格式的使用
  ---业务上没有各种复杂的情况
  ---屏幕之间有较多的转换
  ---业务流程性很强
  ---GUI界面测试
  ---在矩阵表中输入输出很难表示
  二、Matrix(矩阵表)
  Matrix格式的使用
  ---表单、区域、数值、输入文件等存在较多变化
  ---相同的输入,但有不同的平台、浏览器或配置
  ---输入输出用矩阵表达较好
  三、Automated script(自动化脚本)
  使用
  ---自动脚本的选择是根据测试对象、测试工具决定的
  ---编写自动测试脚本比编写手动测试用例要花费更多的时间,因为编写自动化测试脚本之前必须要编写手动测试用例
  ---在软件生命周期的维护阶段,即多次进行回归测试的情况下,可重复使用的自动脚本将起到非常重要的作用
  ---自动测试工具还被用来进行性能测试

posted @ 2014-02-19 10:29 顺其自然EVO 阅读(302) | 评论 (0)编辑 收藏

大数据高并发数据库设计注意要点

 在一个项目实施初始,数据库的设计非常重要,很多时候,我们只关心和考虑到眼前的功能,而忽略了后续的可维护性和可拓展性,以及还有一个在大数据时代会遇到的高并发问题。
  在设计表结构时要注意以下几个要点:
  1.数据行的长度不要超过8020字节,如果超过这个长度的话在物理页中这条数据会占用两行从而造成存储碎片,降低查询效率。
  2.能够用数字类型的字段尽量选择数字类型而不用字符串类型的(电话号码),这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接回逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
  3.对于不可变字符类型char和可变字符类型varchar 都是8000字节,char查询快,但是耗存储空间,varchar查询相对慢一些但是节省存储空间。在设计字段的时候可以灵活选择,例如用户名、密码等长度变化不大的字段可以选择CHAR,对于评论等长度变化大的字段可以选择VARCHAR。
  4.字段的长度在最大限度的满足可能的需要的前提下,应该尽可能的设得短一些,这样可以提高查询的效率,而且在建立索引的时候也可以减少资源的消耗。
  查询语句优化要点:
  1.尽可能使用索引
  2.查询有先后顺序,注意把快速条件或者索引查询放在前面
  3.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
  select id from t where num=10 or num=20
  可以这样查询:
select id from t where num=10
union all
select id from t where num=20
  4.要避免在where中使用表达式,这样将放弃索引,进行全表查询

posted @ 2014-02-18 11:32 顺其自然EVO 阅读(1282) | 评论 (0)编辑 收藏

【Loadrunner】解决客户端生成和引用GUID的方法

 方法:
  1、将生成GUID方法放在新建的GUID.h文件中;
  2、把这个文件放入脚本保存处;
  3、在globals.h中增加函数头“#include "GUID.h"”;
  4、直接引用(备注:如果要将生成的GUID
  作为请求参数,必须先用lr_save_string函数转换成LoadRunner能识别的参数,否则无法使用)
char* lr_guid_gen(char* paramName){                         //生成GUID方法
typedef struct _GUID    {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
} GUID;
GUID m_guid;
char buf[50];
char pNameStr[50];
CoCreateGuid(&m_guid);
// 定义输出格式
//sprintf (buf, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", // 大写
// sprintf (buf, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",// 小写
sprintf (buf, "%08lX%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",// 小写
m_guid.Data1, m_guid.Data2, m_guid.Data3,
m_guid.Data4[0], m_guid.Data4[1], m_guid.Data4[2], m_guid.Data4[3],
m_guid.Data4[4], m_guid.Data4[5], m_guid.Data4[6], m_guid.Data4[7]);
lr_save_string(buf, paramName);
sprintf(pNameStr,"{%s}",paramName);
return lr_eval_string(pNameStr);
}
Action()
{
char *test;
lr_load_dll("ole32.dll");      //引用windows生成GUID的API
test=lr_guid_gen("GUID");      //调用上面lr_guid_gen()方法
lr_save_string(test,"GUID");
lr_output_message(test);
lr_output_message("xxxxxxxxxxxxx:%s",lr_eval_string("{GUID}"));
return 0;
}
  备注:1、生成GUID方法是在网上借鉴后,通过加工编写而成,2、此脚本是为了帮助一个朋友解决GUID问题

posted @ 2014-02-18 11:31 顺其自然EVO 阅读(1137) | 评论 (1)编辑 收藏

Java Socket常见异常处理

 java网络编程Socket通信中,通常会遇到以下异常情况:
  第1个异常是 java.net.BindException:Address already in use: JVM_Bind。
  该异常发生在服务器端进行new ServerSocket(port)(port是一个0,65536的整型值)操作时。异常的原因是以为与port一样的一个端口已经被启动,并进行监听。此时用netstat -an命令,可以看到一个Listending状态的端口。只需要找一个没有被占用的端口就能解决该问题了。
  第2个异常是java.net.ConnectException: Connection refused: connect。
  该异常发生在客户端进行 new Socket(ip, port)操作时,该异常发生的原因是或者具有ip地址的机器不能找到(也就是说从当前机器不存在到指定ip路由),或者是该ip存在,但找不到指定的端口进行监听。出现该问题,首先检查客户端的ip和port是否写错,如果正确则从客户端ping一下服务器看是否能ping通,如果能ping通(服务器端把ping禁掉则需要另外的办法),则看在服务器端的监听指定端口的程序是否启动,这个肯定能解决这个问题。
  第3个异常是java.net.SocketException: Socket is closed。
  该异常在客户端和服务器均可能发生。异常的原因是本端主动关闭了连接后(调用了Socket的close方法)再对网络连接进行读写操作。
  第4个异常是java.net.SocketException: (Connection reset或者Connect reset by peer:Socket write error)。
  该异常在客户端和服务器端均有可能发生,引起该异常的原因有两个,第一个就是如果一端的Socket被关闭(或主动关闭或者因为异常退出而引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。另一个是一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。简单的说就是由连接断开后的读和写操作引起的。
  第5个异常是java.net.SocketException: Broken pipe。
  该异常在客户端和服务器均有可能发生。在第4个异常的第一种情况中(也就是抛出 SocketExcepton:Connect reset by peer:Socket write error后),如果再继续写数据则抛出该异常。前两个异常的解决方法是首先确保程序退出前关闭所有的网络连接,其次是要检测对方的关闭连接操作,发现对方关闭连接后自己也要关闭该连接。
  二.编写网络程序时需要注意的问题:
  1、是要正确区分长、短连接。所谓的长连接是指一经建立就永久保持。短连接的情况是,准备数据—>建立连接—>发送数据—>关闭连接。很多的程序员写了多年的网络程序,居然不知道什么是长连接,什么是短连接。
  2、是对长连接的维护。所谓维护包括两个方面,首先是检测对方的主动断连(即调用 Socket的close方法),其次是检测对方的宕机、异常退出及网络不通。这是一个健壮的通信程序必须具备的。检测对方的主动断连很简单,主要一方主动断连,另一方如果在进行读操作,则此时的返回值只-1,一旦检测到对方断连,则应该主动关闭本端的连接(调用Socket的close方法)。而检测对方的宕机、异常退出及网络不通,常用方法是用“心跳”,也就是双方周期性的发送数据给对方,同时也从对方接收“心跳”,如果连续几个周期都没有收到对方心跳,则可以判断对方宕机、异常退出或者网络不通,此时也需要主动关闭本端连接,如果是客户端可在延迟一定时间后重新发起连接。虽然Socket有一个keep alive选项来维护连接,如果用该选项,一般需要两个小时才能发现对方的宕机、异常退出及网络不通。
  3、是处理效率问题。不管是客户端还是服务器,如果是长连接一个程序至少需要两个线程,一个用于接收数据,一个用于发送心跳,写数据不需要专门的线程,当然另外还需要一类线程(俗称Worker线程)用于进行消息的处理,也就是说接收线程仅仅负责接收数据,然后再分发给Worker进行数据的处理。如果是短连接,则不需要发送心跳的线程,如果是服务器还需要一个专门的线程负责进行连接请求的监听。这些是一个通信程序的整体要求,具体到你的程序中,就看你如何对程序进行优化了。

posted @ 2014-02-18 11:31 顺其自然EVO 阅读(2506) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 147 148 149 150 151 152 153 154 155 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜