https://www.cnblogs.com/MrYuan/p/5215923.html
https://blog.csdn.net/qq_41787205/article/details/86694417
本机端口查看
打开DOS窗口后,一般我们会先输入“netstat”命令查看简单的统计信息,其中冒号后面的是端口信息:
输入“netstat -nao”命令时可以在最右列显示PID进程序号,以便我们用命令直接结束程序:
输入“netstat -nab”命令可以网络连接、端口占用和程序运行的详细信息
然后用任务管理器看对应的进程。
利用快捷键win+R键打开运行窗口。输入cmd回车打开命令提示符窗口
1:查看本机开放的端口,即已被占用的端口号。 命令: netstat -an
部分结果列表:
Proto Local Address Foreign Address State
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING
TCP 0.0.0.0:3473 0.0.0.0:0 LISTENING
TCP 0.0.0.0:8009 0.0.0.0:0 LISTENING
Local Addresss 对应的这列,“:”后边即为以开放的端口号。
2:查看某个端口号是否被占用 netstat -ano|findstr "3306" (注意双引号前面有个空格)
可以看到,输入端口号“3306”和"51016"都没有返回任何值,说明这两个端口没有被占用,
而输入端口号”52475“后看到,出现了2行返回结果,说明这个端口被占用了
3:查看进程号对应的进程名称 tasklist|findstr ”9400“
注意:这里输入的不是端口号,而是后面显示的端口号对应的进程号
可以看到,输入进程号9400后,显示了该进程号对应的进程名,即360se.exe
4:结束进程 tskill 360se.exe
tskill 进程名/进程号
也可以直接在任务管理器中结束,打开任务管理器快捷键:ctrl+shift+ESC 命令:
小知识:Netstat命令用法命令格式:
Netstat -a -e -n -o -s-an-a 表示显示所有活动的TCP连接以及计算机监听的TCP和UDP端口。
-e 表示显示以太网发送和接收的字节数、数据包数等。
-n 表示只以数字形式显示所有活动的TCP连接的地址和端口号。
-o 表示显示活动的TCP连接并包括每个连接的进程ID(PID)。
-s 表示按协议显示各种连接的统计信息,包括端口号。
-an 查看所有开放的端口
delete和析构函数间的关系及细节
https://blog.csdn.net/wk_bjut_edu_cn/article/details/79149540
https://blog.csdn.net/lzm18064126848/article/details/50392164
#include #include using namespace std; class shape { public: char x; shape(char m) { x=m; cout << "构造"<<endl; cout <<x<<endl; } ~shape() { cout << "析构"<<endl; cout<<x<<endl; } }; int main() { shape a('a'); shape* b = new shape('b'); delete b; system("pause"); return 0; }
当有那句delete b时,运行结果如图,也就是说delete b之后执行了shape的析构函数,而按了任意键之后,会立马闪出一个析构a来,这说明程序执行完成后,即在a所在的作用域结束后,执行了shape的析构函数
而当没有delete b时,运行结果如图,这说明暂时没有执行b的shape析构函数,按了任意键后,跟上面一样,也只会闪出一个析构a来,没有析构b
这说明,直接声明的对象,比如shape a,即在栈上面的对象,所在作用域结束后,会自动执行析构函数,而new出来的在堆上的对象,不调用delete,即使它所在的作用域已经结束,也不会调用析构函数,根据另外一篇文章内所述,可能程序结束后,OS(操作系统)会回收其堆内占用的内存,这样就不知道会干什么,会不会调用析构了。
delete详解:首先调用析构函数,完成类成员的释放,比如类成员有vector也指向了堆上的内存,就需要在析构函数中同样使用delete释放这块内存,或者说它自身处于一个容器当中,就需要在这个容器中erase它
然后再free掉整个对象的内存;
delete b过后,b仍然指向改内存,即地址不变,但指针可能为悬垂指针,访问它可能带来意想不到的结果,也可能正确访问,不确定,所以建议delete后,把指针设置成NULL,后面也可根据指针是否为NULL判断是否可用
inet_addr()将命令行中输入的点分IP地址转换为二进制表示的网络字节序IP地址
inet_ntoa()和上面那个相反
https://blog.csdn.net/bit666888/article/details/81746085
地址转换函数:inet_ntoa() 和 inet_addr()
inet_ntoa():
函数原型:
char *inet_ntoa(struct in_addr);
参数:in_addr是一个结构体,用来表示一个32位的IPV4地址。
struct in_addr{ in_addr_t s_addr; }
返回值:返回点分十进制的字符串在静态内存中的指针。
点分十进制:
全称为点分(点式)十进制表示法,是IPV4的IP地址标识方法。
IPV4中用4个字节表示一个IP地址,每个字节按照十进制表示为0~255。
点分十进制就是用4个从0~255的数字,来表示一个IP地址。
例如:192.168.1.246
头文件:<arpa/inet.h>
别称:IP地址转换函数。
功能:将网络字节序IP转化成点分十进制IP
网络字节序:网络字节序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian(大端)排序方式。
inet_addr():
简介:
inet_addr方法可以转化字符串,主要用来将一个十进制的数转化为二进制的数,用途多余IPV4的IP转化。
函数原型:
in_addr_t inet_addr(const char* cp);
参数:字符串,一个点分十进制的IP地址。
返回值:
若字符串有效,则将字符串转换为32位二进制网络字节序的IPV4地址;否则,为INADDR_NONE
头文件:<arpa/inet.h>
别称:IP地址转化函数。
功能:将一个点分十进制的IP转换成一个长整数型(u_long类型)。
https://www.cnblogs.com/crazyleeyang/articles/2446146.html
sockaddr与sockaddr_in及其使用
编了有不少的socket相关的例子了,同时在现在的项目中常用到socket编程,今天突然发现对与socket编程中的地址使用还不是很熟练,于是综合一下网上的资料,详细探讨下.首先要说明的是这里主要探讨struct sockaddr 与struct sockaddr_in两个结构体.在linux环境下,结构体struct sockaddr在/usr/include/linux/socket.h中定义,具体定义如下:
typedef unsigned short sa_family_t; struct sockaddr { sa_family_t sa_family; /* 地址族,一般都是“AF_xxx”的形式,通常用的是AF_INET,2个字节 */ char sa_data[14]; /* 14字节的协议地址,包含该socket的IP地址和端口等信息 */ };
这是通用socket地址(共16字节).具体到internet环境下使用的socket的地址为sockaddr_in,二者长度一样,都是16个字节.二者可以进行类型转换.一般情况下,需要把sockaddr_in结构强制转换成sockaddr再传入系统调用函数中.
struct sockaddr_in { short int sin_family; /* 地址族,形如AF_xxx,通常用的是AF_INET,2字节 */ unsigned short int sin_port; /* 端口号(使用网络字节顺序)2字节 */ struct in_addr sin_addr; /* 存储IP地址,4字节,就是32位的ip地址 */ unsigned char sin_zero[8]; /* 总共8个字节,实际上没有什么用,只是为了和struct sockaddr保持一样的长度 */ };
struct in_addr其实就是32位IP地址,下面是in_addr的结构:
struct in_addr { unsigned long s_addr; };
还有另一种形式,如下:
struct in_addr { union { struct{unsigned char s_b1,s_b2,s_b3,s_b4;} S_un_b; struct{unsigned short s_w1,s_w2;} S_un_w; unsigned long S_addr;//4字节,32位,按照网络字节顺序存储IP地址 } S_un; };
关于网络字节顺序:其实数据的顺序是由cpu决定的,与操作系统无关,如 Intel x86结构下,short型数0x1234表示为34 12,int型数0x12345678表示为78 56 34 12(小端数据),如IBM power PC结构下,short型数0x1234表示为12 34,int型数0x12345678表示为12 34 56 78,则为大端数据.在网络传输时需要做好转换,网络字节顺序为大端字节顺序.下面是一些用于转换的函数.
htons:把unsigned short类型从主机序转换到网络序;
htonl:把unsigned long 类型从主机序转换到网络序;
ntohs:把unsigned short类型从网络序转换到主机序;
ntohl:把unsigned long 类型从网络序转换到主机序;
inet_aton(const char *string, struct in_addr*addr):将一个字符串IP地址转换为一个32位的网络序列IP地址
inet_addr:是将一个点分制的IP地址(如192.168.0.1)转换为上述结构中需要的32位IP地址(0xC0A80001),即转换成in_addr,inet_addr()返回的地址已经是网络字节格式,所以无需再调用函数htonl();
inet_ntoa(struct in_addr):返回点分十进制的字符串在静态内存中的指针,所以每次调用 inet_ntoa(),它就将覆盖上次调用时所得的IP地址.
inet_pton(int af, const char *src, void *dst):函数将点分十进制的地址src转换为in_addr的结构体,并复制在dst中.
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt):转换网络二进制结构到点分十进制类型的地址
例子:
my_addr.sin_family = AF_INET; /* 主机字节序 */ my_addr.sin_port = htons(MYPORT); /* short, 网络字节序 */ my_addr.sin_addr.s_addr = htonl(INADDR_ANY); //还有如此的格式 my_addr.sin_addr.s_addr = inet_addr("192.168.0.1");
一般编程中并不直接针对sockaddr操作,而是使用sockaddr_in来进行操作.要做转换的时候用:(struct sockaddr*)mysock_addr,填值的时候使用sockaddr_in结构,而作为函数的参数传入的时候转换成sockaddr结构就行了.
计算机网络高级软件编程技术P80页
对于抓到的包进行端口过滤或者进行ip地址过滤。
端口号一般http协议是默认80端口,https协议是使用443端口,还有其他的上网查。
然后对于一个网站的ip地址,可以通过在cmd命令行用ping + 网址。比如csdn的使用ping blog.csdn.net可以得到csdn的ip地址。对于tcp头还要在学习一下!!!!!!!!!!!!!!!!!!!
#include<winsock2.h> #include<iphlpapi.h> #include <Ws2tcpip.h> #include<iostream> #include<conio.h> #include <time.h> #define IO_RCVALL _WSAIOW(IOC_VENDOR, 1) #define BUFFER_SIZE 65535 using namespace std; typedef pair<int, BYTE> pii; char localName[256];//本地机器名 DWORD dwBufferLen[10];//获取主机名 DWORD dwBufferInLen = 1;//指向主机信息的指针 DWORD dwBytesReturned = 0;//通过主机名获取本地IP地址 char buffer[BUFFER_SIZE]; class CIPNode{ public: ULONG m_dwSourIpAddr;//源IP地址 ULONG m_dwDestIpAddr;//目的IP地址 BYTE m_chProtocol;//IP包的协议类型 ULONG m_dwCounter;//数据包的数量 CIPNode *pNext;//指向下一类IP节点 CIPNode (ULONG dwSourIp, ULONG dwDestIp, BYTE chPro) { m_dwSourIpAddr = dwSourIp; m_dwDestIpAddr = dwDestIp; m_chProtocol = chPro; m_dwCounter = 1;//初始化数据包个数为1 } void addCount() {//增加数据包的数量 m_dwCounter++; } ULONG getCount() {//取得数据包的数量 return m_dwSourIpAddr; } ULONG getSourIpAddr() {//取得源IP地址 return m_dwSourIpAddr; } ULONG getDestIpAddr() {//取得目的IP地址 return m_dwDestIpAddr; } BYTE getProtocol() {//取得协议类型 return m_chProtocol; } }; string getProtocol(BYTE Protocol) //获取协议字段共8位 { switch(Protocol) //以下为协议号说明: { case 1: return "ICMP"; //Internet控制报文协议 case 2: return "IGMP"; //Internet组管理协议 case 4: return "IP in IP"; //移动IP数据封装和隧道 case 6: return "TCP"; //传输控制协议 case 8: return "EGP"; //外部网关协议 case 17: return "UDP"; //用户数据报文协议 case 41: return "IPv6"; case 46: return "RSVP"; //资源预留协议 case 89: return "OSPF"; //Open Shortest Path First 开发式最短路径优先 default: return "UNKNOW"; } } class CNodeList { private: CIPNode *pHead;//链表头 CIPNode *pTail;//链表尾 public: CNodeList() {//构造函数 pHead = pTail = NULL; } //析构函数,完成类成员的释放。 ~CNodeList() { //删除链表中的所有节点 if(pHead != NULL) { CIPNode *pTemp = pHead; pHead = pHead -> pNext; delete pTemp; pTemp = NULL; } } //把新捕获的IP数据包加入链表。 void addNode(ULONG dwSourIp, ULONG dwDestIp, BYTE chPro) { if(pHead == NULL) {//链表为空 pTail = new CIPNode(dwSourIp, dwDestIp, chPro); pHead = pTail; pTail -> pNext = NULL; } else {//链表不为空 CIPNode *pTemp; for(pTemp = pHead; pTemp; pTemp = pTemp -> pNext) { //如果链表中已存在该类型的IP包,则数据包的个数加1. if(pTemp -> getSourIpAddr() == dwSourIp && pTemp -> getDestIpAddr() == dwDestIp && pTemp -> getProtocol() == chPro) { pTemp -> addCount(); break; } } //如果链表中不存在该类型的IP包,则创建新的节点加入链表。 if(pTemp == NULL) { pTail -> pNext = new CIPNode(dwSourIp, dwDestIp, chPro); pTail = pTail -> pNext; pTail -> pNext = NULL; } } } void print() { CIPNode *pTemp; for(pTemp = pHead; pTemp; pTemp = pTemp -> pNext) { printf("源主机 :%s ", inet_ntoa(*(in_addr*) (&pTemp -> m_dwSourIpAddr)) ); printf("目的主机:%s ", inet_ntoa(*(in_addr*) (&pTemp -> m_dwDestIpAddr)) ); cout << getProtocol(pTemp -> m_chProtocol) << endl; } printf("OVER "); } }; struct IPHEADER {//20-60 BYTE Version_HeaderLength;//版本(4位)+首部长度(4位) BYTE TypeOfService;//服务类型。计算机网络高级编程技术P76 USHORT TotalLength;//总长度 USHORT Identification;//标识 USHORT Flags_FragmentOffset;//标志(3位)+分片偏移(13位) BYTE TimeToLive;//生存时间 BYTE Protocol;//协议 USHORT HeaderChecksum;//首部校验和 ULONG SourceAddress;//源ip地址 ULONG DestAddress;//目的ip地址 // BYTE Options//选项 }; //20-60 struct Tcphead{ USHORT SourcePort;//源端口号 USHORT DestPort;//目的端口号 ULONG dwSeq;//序号 ULONG dwAck;//确认序号 BYTE Length; USHORT flag; USHORT Window; USHORT CheckSum; USHORT Urgent; // ULONG Options; }; struct Udphead{ USHORT SourcePort; USHORT DestPort; USHORT Length; USHORT CheckSum; }; int cnt; pii printip(IPHEADER *iphead) { // cout << "第 "<<cnt++<<" 个IP数据包信息:" << endl; // cout << "协议版本:" <<(iphead -> Version_HeaderLength >> 4) << endl; // cout << "首部长度:" << ((iphead -> Version_HeaderLength & 0x0F) << 2) << endl;//单位为4字节,所以乘四。 // cout << "优先级:Priority: " << ((iphead -> TypeOfService) >> 5) << ",服务类型:Service: " // << (( (iphead -> TypeOfService) >> 1) & 0x0f) << endl; // cout << "IP包总长度:" << ntohs(iphead -> TotalLength) << endl; //网络字节序转为主机字节序 // cout << "标识:" << ntohs(iphead -> Identification) << endl;//网络字节序转成主机字节序 // cout << "标志位:" << "DF=" << ((iphead -> Flags_FragmentOffset >> 14) & 0x01); // cout << ",MF=" << ((iphead -> Flags_FragmentOffset >> 13) & 0x01) << endl; // //共3位,最高位为0;DF禁止分片标识。DF=0,可以分片;DF=1,不能分片。MF:分片标识。 // //MF=0,表示接的是最后一个分片;MF=1,不是最后一个分片。 // cout << "片偏移:" << (iphead -> Flags_FragmentOffset & 0x1fff) << endl;//得到后13位 // cout << "生存周期:" << (int)iphead -> TimeToLive << endl; // cout << "协议类型:" << getProtocol(iphead -> Protocol) << endl; // cout << "首部校验和:" << ntohs(iphead -> HeaderChecksum) << endl; // cout << "源地址:" << inet_ntoa(*(in_addr*)(&iphead -> SourceAddress) ) << endl; // cout << "目的地址:" << inet_ntoa(*(in_addr*) (&iphead -> DestAddress) ) << endl; // cout << "==============================================================" << endl << endl; return make_pair((iphead -> Version_HeaderLength & 0x0F) << 2, iphead -> Protocol); } int main() { clock_t start = clock(); WSADATA wsData; WSAStartup(MAKEWORD(2, 2), &wsData); SOCKET sock; sock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED); gethostname(localName, 256); HOSTENT *pHost; pHost = gethostbyname(localName); sockaddr_in addr_in; addr_in.sin_family = AF_INET;//设定地址类型 addr_in.sin_port = htons(8000);//设定一个端口。不能是已固定的端口 for(DWORD i = 0; pHost -> h_addr_list[i]; i++) { printf ("IP address %lu:%s ", i + 1, inet_ntoa (*(struct in_addr*)pHost->h_addr_list[i])); } int ind; scanf("%d", &ind); addr_in.sin_addr = *(in_addr *) pHost->h_addr_list[ind];//设置IP地址 bind(sock, (sockaddr *) &addr_in, sizeof(addr_in));//把原始套接字绑定到本机地址上 //设置混杂模式 WSAIoctl(sock, IO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen), dwBufferLen, sizeof(dwBufferLen), &dwBytesReturned, NULL, NULL); // ULONG bioarg = 0; // ioctlsocket(sock, FIONBIO, &bioarg); CNodeList IpList; while(1) { int nPackSize = recv(sock, buffer, BUFFER_SIZE, 0); if(nPackSize > 0) { IPHEADER *pIpHdr; //通过指针把缓冲区中的内容强制转换为IPHEADER数据结构。 pIpHdr = (IPHEADER *) buffer; pii x = printip(pIpHdr); int xx; in_addr csdn; csdn.S_un.S_addr = inet_addr("202.202.32.35"); if(x.second == 6) { Tcphead *pTcphdr; pTcphdr=(struct Tcphead*)(buffer+(x.first)); printf("%d ", (((pTcphdr -> Length) & 0xF0)>>4) * 4); printf("源端口%d, 目的端口%d ", ntohs(pTcphdr -> SourcePort), ntohs(pTcphdr -> DestPort)); if( (pTcphdr -> SourcePort) == ntohs(80) && (pIpHdr -> SourceAddress) == csdn.S_un.S_addr) { printf("%s ", inet_ntoa(*(in_addr*) (&pIpHdr -> SourceAddress) )); printf("出去%s ", buffer + (x.first) + (((pTcphdr -> Length) & 0xF0)>>4) * 4); scanf("%d", &xx); } if( (pTcphdr -> DestPort) == ntohs(80) && (pIpHdr -> DestAddress) == csdn.S_un.S_addr) { printf("%s ", inet_ntoa(*(in_addr*) (&pIpHdr -> DestAddress) )); printf("进来%s ", buffer + (x.first) + (((pTcphdr -> Length) & 0xF0)>>4) * 4); scanf("%d", &xx); } } // else if(x.second == 17) { // Udphead *pUdphdr; // pUdphdr=(struct Udphead*)(buffer+(x.first*4)); // printf("源端口%d, 目的端口%d ", pUdphdr -> SourcePort, pUdphdr -> DestPort); // if(pUdphdr -> SourcePort == 80) { // // } // } // TCPPORT *tcpPort; // printf("%d ", x); // tcpPort = (TCPPORT *) (buffer + x); // printf("源端口%u 目的端口%u ", tcpPort -> SourcePort, tcpPort -> DestPort); //判断IP包的源IP地址或目的IP地址是否为本地主机的IP地址。 if(pIpHdr -> SourceAddress == addr_in.sin_addr.S_un.S_addr || pIpHdr -> DestAddress == addr_in.sin_addr.S_un.S_addr) { IpList.addNode(pIpHdr -> SourceAddress, pIpHdr -> DestAddress, pIpHdr -> Protocol); } // printf("继续yes/no "); // char ch[4]; // scanf("%s", ch); // if(ch[0] == 'y') continue; // else break; } // if(clock() - start >= 2000) break; } IpList.print(); closesocket(sock); WSACleanup(); return 0; }
http://blog.chinaunix.net/uid-26729093-id-3444880.html?_t=t
https://blog.csdn.net/weixin_34198762/article/details/86037650