如何用Qt在linux下实现ping命令?

lxsmartcard 2010-09-09 11:36:29
RT



请那位高手给指点一下,因为是嵌入式下实现ping命令,不能通过QProcess()调用linux自带的ping。


非常感谢!
...全文
696 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
donwmufromdying 2013-05-24
  • 打赏
  • 举报
回复
	typedef struct tagIPHDR
	{
		u_char VIHL; // Version and IHL
		u_char TOS; // Type Of Service
		short TotLen; // Total Length
		short ID; // Identification
		short FlagOff; // Flags and Fragment Offset
		u_char TTL; // Time To Live
		u_char Protocol; // Protocol
		u_short Checksum; // Checksum
		struct in_addr iaSrc; // Internet Address - Source
		struct in_addr iaDst; // Internet Address - Destination
	}IPHDR, *PIPHDR;
	
	// ICMP Header - RFC 792
	typedef struct tagICMPHDR
	{
		u_char Type; // Type
		u_char Code; // Code
		u_short Checksum; // Checksum
		u_short ID; // Identification
		u_short Seq; // Sequence
		char Data; // Data
	}ICMPHDR, *PICMPHDR;
donwmufromdying 2013-05-24
  • 打赏
  • 举报
回复
我发一个下的很乱的一个。你参考一下吧。这是我的一个手下程序员写的。写的稍微垃圾了点
	
// ICMP Echo Request
	typedef struct tagECHOREQUEST
	{
		ICMPHDR icmpHdr;
		struct timeval echoTime;
		char cData[REQ_DATASIZE];
	}ECHOREQUEST, *PECHOREQUEST;
	
	// ICMP Echo Reply
	typedef struct tagECHOREPLY
	{
		IPHDR ipHdr;
		ECHOREQUEST echoRequest;
		char cFiller[256];
	}ECHOREPLY, *PECHOREPLY;
        int sockfd = 0;
	int nRet;
	int nCount;
	int iSuccess = 0;
	struct sockaddr_in addrDest;
	struct hostent *Dest;
	float spenttime;

	if ((Dest=gethostbyname(shost)) == NULL)
	{
		return false;
	}
	if((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
	{ 
		return false;
	} 
	memset((sockaddr_in*)&addrDest, 0, sizeof(struct sockaddr_in));
	addrDest.sin_addr = *((struct in_addr *)Dest->h_addr);
	addrDest.sin_family = AF_INET;
	bzero(&(addrDest.sin_zero), 8); 
	ECHOREQUEST echoReq;
	memset((ECHOREQUEST*)&echoReq, 0, sizeof(struct tagECHOREQUEST));
	echoReq.icmpHdr.Type = ICMP_ECHO;
	echoReq.icmpHdr.Code = 0;
	echoReq.icmpHdr.ID = getpid();
	int Seq = 0;
	for (nRet = 0; nRet < REQ_DATASIZE; nRet++)
		echoReq.cData[nRet] = ' '+nRet;
	nCount = 0;
	while(nCount < 3)
	{
		echoReq.icmpHdr.Seq = Seq++;
		echoReq.icmpHdr.Checksum = 0;
		gettimeofday(&echoReq.echoTime,NULL);
		echoReq.icmpHdr.Checksum = checksum((unsigned short*)&echoReq, sizeof(struct tagECHOREQUEST));
		if (sendto(sockfd, (ECHOREQUEST*)&echoReq, sizeof(tagECHOREQUEST), 0, (struct sockaddr *)&addrDest, sizeof(addrDest)) < 0)
		{ 
			close(sockfd);
			return false;
		}
		if(WaitForEchoReply(sockfd) == -1)
		{
			close(sockfd);
			return false;
		}
		ECHOREPLY icmpRecv;
		int addr_len;
		addr_len = sizeof(struct sockaddr);
		if (recvfrom(sockfd, (ECHOREPLY*)&icmpRecv, sizeof(struct tagECHOREPLY), 0, (struct sockaddr *)&addrDest, (socklen_t *)&addr_len) < 0)
		{ 
			
			close(sockfd);
			return false;
		}
		else if(icmpRecv.echoRequest.icmpHdr.Type == ICMP_ECHOREPLY)
		{
			gettimeofday(&icmpRecv.echoRequest.echoTime, NULL);
			tv_sub(&icmpRecv.echoRequest.echoTime, &echoReq.echoTime);
			spenttime=icmpRecv.echoRequest.echoTime.tv_sec*1000+icmpRecv.echoRequest.echoTime.tv_usec*0.001;
			if (strcmp(Dest->h_name, inet_ntoa(icmpRecv.ipHdr.iaSrc))==0) 
			{		
				iSuccess ++;
			//	printf("Reply from %s: Bytes=%d Id_seq = %d time=%4.3fms TTL=%d\n",/*Dest->h_name*/inet_ntoa(icmpRecv.ipHdr.iaSrc), sizeof(icmpRecv.echoRequest), icmpRecv.echoRequest.icmpHdr.Seq, spenttime,icmpRecv.ipHdr.TTL);
			}
			else
			{
			;	//printf("From %s Id_seq %d Destination Host Unreachable ", inet_ntoa(icmpRecv.ipHdr.iaSrc), icmpRecv.echoRequest.icmpHdr.Seq);
			}
		//	sleep(1);
		}
		nCount ++;
	}
	close(sockfd);
	if (iSuccess >0)
		return true;
	else
		return false;
注释一行 2013-05-24
  • 打赏
  • 举报
回复
char* ch; liv_s = ui->linet_ip->text(); QString pinip= "ping "+liv_s+ " -c 3"; qDebug()<<pinip; QByteArray ba = pinip.toLatin1(); ch=ba.data(); int ret=system(ch); qDebug()<<ret; if(ret!=0) { ui->label->setText(tr("网络断开!!")); } else { ui->label->setText(tr("网络已连接!!")); }
lynnhua_ 2013-05-23
  • 打赏
  • 举报
回复
如果楼主已解决该问题,希望共享下代码,感激!
ailinty 2010-09-14
  • 打赏
  • 举报
回复
QT 调用 linux下的C 按理说不会出什么错的。顶楼上。
gemfield 2010-09-13
  • 打赏
  • 举报
回复
在linux下实现ping命令就比较容易了,Qt可以直接使用linux的函数。不知道为啥说不能调用?
dext 2010-09-10
  • 打赏
  • 举报
回复
Linux 下的 ping.c 源代码中有这么一行

sockRaw = socket ( AF_INET, SOCK_RAW,IPPROTO_ICMP );

也就是说,他不是 TCP 和 UDP 的,(Qt 提供了 QTcpSocket 和 TUdpSocket)

所以,在Qt 下,也很简单,直接写一个 QIcmpSocket 继承于 QAbstractSocket
实现 ICMP 协议就可以了。
lxsmartcard 2010-09-10
  • 打赏
  • 举报
回复
非常感谢你的回答!

能否再详细一些,具体讲解一下如何写一个 QIcmpSocket

[Quote=引用 3 楼 dext 的回复:]
Linux 下的 ping.c 源代码中有这么一行

sockRaw = socket ( AF_INET, SOCK_RAW,IPPROTO_ICMP );

也就是说,他不是 TCP 和 UDP 的,(Qt 提供了 QTcpSocket 和 TUdpSocket)

所以,在Qt 下,也很简单,直接写一个 QIcmpSocket 继承于 QAbstractSocket
实现 ……
[/Quote]
xushiq 2010-09-10
  • 打赏
  • 举报
回复
这确实不错 学习了
tingsking18 2010-09-09
  • 打赏
  • 举报
回复
那就得看看ICMP协议了
lxsmartcard 2010-09-09
  • 打赏
  • 举报
回复
看了icmp协议,不太明白。能否给详细分析一下,最好能结合QT平台。

非常感谢!
[Quote=引用 1 楼 tingsking18 的回复:]
那就得看看ICMP协议了
[/Quote]

16,212

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧