网上查到,Android下的原始套接字 需要机子root之后才能使用(机子root之后到底能不能使用,我没测试过[20151103])。
PS:我看了一下,java实现的 的与那吗里面也是使用的jni方式。看了 jpcap-0.6.rar 的源码,貌似也是jni。
使用下面这个 Qt代码,在创建 套接字的部分 会返回错误代码(我遇到的是 errno 返回 1 或者 93):
(工程的 AndroidManifest.xml 文件里面已经加入
“
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
”)
#include "MainWindow.h"#include "ui_MainWindow.h"#include#include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ ui->setupUi(this); //ui->textEdit->append(); //ui->plainTextEdit->appendPlainText();}MainWindow::~MainWindow(){ delete ui;}int g_i01 = 0;int g_i02 = 0;void MainWindow::on_pbtnTextEdit_clicked(){ //ui->textEdit->setReadOnly(true); ui->textEdit->append(QString::number(g_i01)); g_i01 ++;// http://www.w-cun.com/post/diaozheng_1976.htm// http://stackoverflow.com/questions/7411761/how-to-increase-qtablewidget-vertical-scrollbar-width int iWidth = ui->plainTextEdit->verticalScrollBar()->width(); QMessageBox::about(this, "title", QString::number(iWidth)); ui->plainTextEdit->verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: "+QString::number(iWidth * 2)+"px; }");}void MainWindow::on_pbtnPlainTextEdit_clicked(){/* ui->plainTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); QScrollBar* pScrollBar = ui->plainTextEdit->verticalScrollBar(); pScrollBar->resize(pScrollBar->width() *2, pScrollBar->height());*/ ui->lineEdit->setReadOnly(true); ui->plainTextEdit->setReadOnly(true); //ui->textEdit->sel ui->plainTextEdit->appendPlainText(QString::number(g_i02)); g_i02 ++; qDebug() << "on_pbtnPlainTextEdit_clicked";/* QTextCharFormat fmt; fmt.setBackground(Qt::yellow); QTextCursor cursor(ui->plainTextEdit->document()); cursor.setPosition(begin, QTextCursor::MoveAnchor); cursor.setPosition(end, QTextCursor::KeepAnchor); cursor.setCharFormat(fmt); */}int main_z();void* thread_z(void* arg);void MainWindow::on_pushButton_clicked(){ pthread_t tid1 = 0; int iRtn = pthread_create(&tid1, NULL, thread_z, &tid1); if(iRtn != 0) { QString str1 = __func__; QString str2 = strerror(iRtn); qDebug() << str1 + str2; } //main_z(); QMessageBox::about(this, "on_pushButton_clicked", "after main_z");}void* thread_z(void* arg){ main_z();}// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***#include #include #include #include #include #include #include #include #include #include #include // 函数close()#include typedef struct _iphdr //定义IP首部{ unsigned char h_verlen; //4位首部长度+4位IP版本号 unsigned char tos; //8位服务类型TOS unsigned short total_len; //16位总长度(字节) unsigned short ident; //16位标识 unsigned short frag_and_flags; //3位标志位 unsigned char ttl; //8位生存时间 TTL unsigned char proto; //8位协议 (TCP, UDP 或其他) unsigned short checksum; //16位IP首部校验和 unsigned int sourceIP; //32位源IP地址 unsigned int destIP; //32位目的IP地址}IP_HEADER;typedef struct _udphdr //定义UDP首部{ unsigned short uh_sport; //16位源端口 unsigned short uh_dport; //16位目的端口 unsigned int uh_len;//16位UDP包长度 unsigned int uh_sum;//16位校验和}UDP_HEADER;typedef struct _tcphdr //定义TCP首部{ unsigned short th_sport; //16位源端口 unsigned short th_dport; //16位目的端口 unsigned int th_seq; //32位序列号 unsigned int th_ack; //32位确认号 unsigned char th_lenres;//4位首部长度/6位保留字 unsigned char th_flag; //6位标志位 unsigned short th_win; //16位窗口大小 unsigned short th_sum; //16位校验和 unsigned short th_urp; //16位紧急数据偏移量}TCP_HEADER;typedef struct _icmphdr { unsigned char icmp_type; unsigned char icmp_code; /* type sub code */ unsigned short icmp_cksum; unsigned short icmp_id; unsigned short icmp_seq; /* This is not the std header, but we reserve space for time */ unsigned short icmp_timestamp;}ICMP_HEADER;void analyseIP(IP_HEADER *ip){ unsigned char* p = (unsigned char*)&ip->sourceIP; printf("Source IP\t: %u.%u.%u.%u\n",p[0],p[1],p[2],p[3]); p = (unsigned char*)&ip->destIP; printf("Destination IP\t: %u.%u.%u.%u\n",p[0],p[1],p[2],p[3]);}void analyseTCP(TCP_HEADER *tcp){ printf("TCP -----\n"); printf("Source port: %u\n", ntohs(tcp->th_sport)); printf("Dest port: %u\n", ntohs(tcp->th_dport));}void analyseUDP(UDP_HEADER *udp){ printf("UDP -----\n"); printf("Source port: %u\n", ntohs(udp->uh_sport)); printf("Dest port: %u\n", ntohs(udp->uh_dport));}void analyseICMP(ICMP_HEADER *icmp){ printf("ICMP -----\n"); printf("type: %u\n", icmp->icmp_type); printf("sub code: %u\n", icmp->icmp_code);}int main_z(void){ int sockfd; IP_HEADER *ip; char buf[10240]; ssize_t n; qDebug() << "main_z in"; /* capture ip datagram without ethernet header */ //if ((sockfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)))== -1) if ((sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_TCP|IPPROTO_UDP|IPPROTO_ICMP))== -1) //if ((sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_IP))== -1) //int skt = socket(AF_INET, SOCK_STREAM, 0); { qDebug() << "socket error : "+QString::number(errno); printf("socket error!\n"); return 1; } return 0; while (1) { n = recv(sockfd, buf, sizeof(buf), 0); if (n == -1) { printf("recv error!\n"); break; } else if (n==0) continue; //接收数据不包括数据链路帧头 ip = ( IP_HEADER *)(buf); analyseIP(ip); size_t iplen = (ip->h_verlen&0x0f)*4; TCP_HEADER *tcp = (TCP_HEADER *)(buf +iplen); if (ip->proto == IPPROTO_TCP) { TCP_HEADER *tcp = (TCP_HEADER *)(buf +iplen); analyseTCP(tcp); qDebug() << "TCP"; } else if (ip->proto == IPPROTO_UDP) { UDP_HEADER *udp = (UDP_HEADER *)(buf + iplen); analyseUDP(udp); qDebug() << "UDP"; } else if (ip->proto == IPPROTO_ICMP) { ICMP_HEADER *icmp = (ICMP_HEADER *)(buf + iplen); analyseICMP(icmp); qDebug() << "ICMP"; } else if (ip->proto == IPPROTO_IGMP) { printf("IGMP----\n"); qDebug() << "IGMP"; } else { printf("other protocol!\n"); qDebug() << "other protocol !"; } printf("\n\n"); break; } close(sockfd); return 0;}