如何锻炼分析问题的方法?请各位大虾指教~~
来源:互联网 发布:手机质量检测软件 编辑:程序博客网 时间:2024/04/24 19:42
最近在solaris下移植heartbeat模块,遇到了一个问题,就是连接其他节点的crm应用程序,有时出现连接失败的问题。
有时返回return -5,有时return-6
代码如下:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <sys/sockio.h>#include <net/if.h> //struct ifconf 在这里面声明#include <netinet/in.h>#include <inttypes.h>#include <arpa/inet.h> #include <fcntl.h>#include <errno.h>#define CRMPORT 3387#ifndef SOCKET#define SOCKET int#endif#ifndef SOCKET_ERROR#define SOCKET_ERROR (-1)#endif#ifndef INVALID_SOCKET#define INVALID_SOCKET 0#endif//连接指定ip和端口8003,若连接成功,则返回1,否则返回0int checkConnectToIp(const char *ipStr){int sockfd;struct sockaddr_in my_addr;struct timeval timeval_time_out;int ul = 1;memset(&(my_addr), 0, sizeof(my_addr));/* zero my address struct */my_addr.sin_family = AF_INET;/* host byte order */my_addr.sin_port = htons((u_short)CRMPORT);my_addr.sin_addr.s_addr = inet_addr(ipStr); if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {int i = 0;fprintf(stdout, "checkConnectToIp: socket error-%d!\n",i);return(sockfd);}//增加设置超时时间,超时时间设置为500ms//初始化超时时间memset(&timeval_time_out, 0, sizeof(struct timeval));timeval_time_out.tv_sec= 0;//l_sec为超时时间,秒timeval_time_out.tv_usec= 500;//l_usec是毫秒// 设置超时时间,成功返回0/*if (0!=setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeval_time_out, sizeof(struct timeval))){if (0 != closesocket(sockfd))return 0;}*/// 设置socket为非阻塞模式int flag;flag = fcntl(sockfd,F_GETFL,0);flag |= O_NONBLOCK;fcntl(sockfd,F_SETFL,flag);//设置非阻塞char* errMsg;if (connect(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_in)) == 0){close(sockfd);return 1;}else{perror("socket connect");if (errno == EINPROGRESS){printf("connect EINPROGRESS\n");}fd_set fd_set_write;int optval=0;int optlen=sizeof(int);int selectrt = 0;FD_ZERO(&fd_set_write);FD_SET(sockfd, &fd_set_write);selectrt = select(sockfd + 1, NULL, &fd_set_write, NULL, &timeval_time_out);printf("selectrt---%d\n",selectrt);if ( 0 < selectrt){if ( 0!=getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) ){FD_CLR(sockfd, &fd_set_write);close(sockfd);printf("checkConnectToIp:return -4\n");return -4;}printf("optval:%d\n",optval);if (0!=optval){FD_CLR(sockfd, &fd_set_write);close(sockfd);printf("checkConnectToIp:return -5\n");return -5;}FD_CLR(sockfd, &fd_set_write);}else{FD_CLR(sockfd, &fd_set_write);close(sockfd);printf("checkConnectToIp:return -6\n");return -6;}close(sockfd);return 1;}}int main(){int ret = 0;ret = checkConnectToIp("10.151.12.122"); //连对方ipprintf("checkConnectToIp ret ------ %d\n",ret);getchar();return 0;}
先说下我的思路:
1、通过对方ip和端口,与对方进行connect连接。
2、如果能connect成功,则直接return 1。
3、否则,调用select机制进行连接,如果select超时,则return -6;如果通过select机制,有描述符发生变化,即select返回值大于0,则通过getsockopt判断其SO_ERROR状态,如果SO_ERROR返回值为0,则return 1,否则 return -5。
我遇到的问题和在老大的批评+指导下的分析解决方法为:
1、弄了一个对方ip作为服务端的程序,结果总是return -5。 于是查看服务端代码,一看不是tcp socket,用的是udp socket,哎,图省事不行呀!!! 经改正,代码select返回值为1,测试程序return 1。
2、于是放到大环境中startHB去跑,结果连对端节点的crm,有时返回-6,有时返回1。老大看了看,想可能是select函数在solaris平台和windows平台的用法不一样,于是到google里搜索“openindiana man select return”,发现返回值说明如下:
If the timeout argument is a null pointer, select() blocks until an event
causes one of the masks to be returned with a valid (non-zero) value.
If the time limit expires before any event occurs that would cause one
of the masks to be set to a non-zero value, select() completes success-
fully and returns 0.
RETURN VALUES
On successful completion, select() and pselect() return the total num-
ber of bits set in the bit masks. Otherwise, -1 is returned and errno
is set to indicate the error.
The FD_CLR(), FD_SET(), and FD_ZERO() macros return no value. The
FD_ISSET() macro returns a non-zero value if the bit for the file
descriptor fd is set in the file descriptor set pointed to by fdset,
and 0 otherwise.
意思就是:(1)在超时时间内,有事件发生的话,返回非0值,返回值为多少位被置位了。(2)超时时间到了,select成功执行并且返回值为0。(3)返回-1表示函数出错。
那说明该程序在select的用法上没有错。
3、进一步分析:由于有时返回-6,说明走的是超时的流程。老大说:超时?那是不是时间设置的不对?下面现将超时时间由原来的500毫秒改成1秒试试;再不行再改成2秒;如果还不可以,说明不是时间量的问题,看看事件设置上是不是有区别,有问题。将程序超时时间500毫秒改成1秒后,经大环境测试可以,反复测试10次以上没问题。
很多时候我在努力并坚持去解决问题,但是效果不理想,关键在于“方法”,各位大虾都很有经验,可不可以告诉我该如何锻炼分析问题的方法?除了亲身经历外,有没有什么书籍或杂志,论坛值得推荐?谢谢各位啦~~~~~~
- 如何锻炼分析问题的方法?请各位大虾指教~~
- window xp安装不了的问题,请各位大虾指教
- 请各位大虾指教,字符串问题
- 请各位大虾多多指教!
- 请各位大虾多多指教
- ado如何连接广域网上的Sql server 数据库 ,请各位大虾指教,很急啊,头都大了
- Vc++如何实现按钮打开*bmp的文件,请各位大虾指教?
- 有关于c#操作excel的问题 请各位大虾指教
- 请各位大虾多多指教,初学者共同讨论!About C#
- 各位大虾好,小弟初来报到,请多多指教
- 如何进行三相电的计量编程?请大虾们指教
- 咨询咨询,工资问题,请大虾们指教!!
- 请各位高手指教!
- 请各位多多指教
- 请各位大虾们帮帮小弟,谢谢!一个关于产品搜索数据库设计思路的问题
- 请教各位大虾JB的一个问题?
- 关于.net的自定义控件(请各位大虾指正)
- 我有一个很头痛的问题,请各位高手指教!
- Lu系统扩展动态库LuSystem之类及对象
- 寻找对象的方法
- Linux开机自动挂载Windows分区的两种方法
- c++中类对象直接作为函数参数所引起的问题。
- 编程珠玑总结
- 如何锻炼分析问题的方法?请各位大虾指教~~
- 主题:三,android编码规范 & 常用布局 & 常用控件
- csdn的新家
- 《C程序设计》第七章:函数
- vb.net 修改图片大小
- 贪心算法
- Repeater控件的简易绑定
- WARNING: Can't find the Qt version that's associated with this project.
- WPF中绘画和动画(3)