网上查到,Android下的原始套接字 需要机子root之后才能使用(机子root之后到底能不能使用,我没测试过[20151103])。
PS:我看了一下,java实现的 RockSaw 的与那吗里面也是使用的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 <QScrollBar> #include <QMessageBox> #include <QDebug> 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 { "+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 <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <linux/if_packet.h> #include <netinet/if_ether.h> #include <netinet/in.h> #include <unistd.h> // 函数close() #include <errno.h> 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 : %u.%u.%u.%u ",p[0],p[1],p[2],p[3]); p = (unsigned char*)&ip->destIP; printf("Destination IP : %u.%u.%u.%u ",p[0],p[1],p[2],p[3]); } void analyseTCP(TCP_HEADER *tcp) { printf("TCP ----- "); printf("Source port: %u ", ntohs(tcp->th_sport)); printf("Dest port: %u ", ntohs(tcp->th_dport)); } void analyseUDP(UDP_HEADER *udp) { printf("UDP ----- "); printf("Source port: %u ", ntohs(udp->uh_sport)); printf("Dest port: %u ", ntohs(udp->uh_dport)); } void analyseICMP(ICMP_HEADER *icmp) { printf("ICMP ----- "); printf("type: %u ", icmp->icmp_type); printf("sub code: %u ", 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! "); return 1; } return 0; while (1) { n = recv(sockfd, buf, sizeof(buf), 0); if (n == -1) { printf("recv error! "); 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---- "); qDebug() << "IGMP"; } else { printf("other protocol! "); qDebug() << "other protocol !"; } printf(" "); break; } close(sockfd); return 0; }