如何锻炼分析问题的方法?请各位大虾指教~~

最近在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,否则返回0
int 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");  //连对方ip
	printf("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次以上没问题。

很多时候我在努力并坚持去解决问题,但是效果不理想,关键在于“方法”,各位大虾都很有经验,可不可以告诉我该如何锻炼分析问题的方法?除了亲身经历外,有没有什么书籍或杂志,论坛值得推荐?谢谢各位啦~~~~~~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情查看资源内容中使用说明 YOLO高分设计资源源码,详情查看资源内容中使用说明 YOLO高分设计资源源码,详情查看资源内容中使用说明 YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明YOLO高分设计资源源码,详情查看资源内容中使用说明
大虾电子网(sscom)是一个提供海量电子产品信息和服务的在线平台。这个网站为用户提供了一个便捷的途径,可以了解和购买各种类型的电子产品。 首先,大虾电子网汇集了来自全球各个知名品牌的电子产品,涵盖了手机、平板、电脑、数码相机等多个领域。通过这个网站,用户可以一站式地浏览并选择自己喜欢的产品。网站上的产品信息非常详细,包括产品的规格、功能、价格等,用户可以根据自己的需求进行筛选和比较。 其次,大虾电子网还提供了各种购买选择。用户可以选择在线购买,通过网站直接下单。而且,大虾电子网与众多知名电商平台合作,用户还可以选择购买渠道,找到最优惠的价格和优质的服务。此外,大虾电子网还提供了在线客服咨询服务,用户在购买过程中遇到问题可以及时咨询。 除了在线购买,大虾电子网还提供了丰富的资讯和评测内容。用户可以了解到最新的电子产品新闻和行业动态,以及各种产品的专业评测和用户评论。这些内容可以帮助用户更好地了解和选择自己需要的产品。 总之,大虾电子网(sscom)是一个综合性的电子产品信息平台,为用户提供了全方位的服务。用户可以通过这个网站方便地了解和购买各种电子产品,还可以获取到最新的行业动态和产品评测。无论是购买还是了解电子产品,大虾电子网都是一个很好的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值