tcp/ip 详细解析以及网络层简单的发送syn

2023-11-18

利用tcp发送syn,我们可以从网络层进行下发,其实就是组装tcp /ip包发送出去.

 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//#include <asm/types.h>
#include <linux/ip.h>
//#include <linux/tcp_new.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <sys/time.h>

#define getrandom(min, max) ((rand() % (int)(((max)+1) - (min))) + (min))

void send_tcp(int sockfd, struct sockaddr_in *addr);
unsigned short checksum(unsigned short *buffer, int size);
unsigned short random_port(unsigned short minport, unsigned short maxport);
void random_ip(char *str);

//nmap:sudo nmap -sP 192.168.1.* 检测内网ip
//nmap:sudo nmap -sS 192.168.1.2 -D 192.168.1.3 用后面的假ip欺诈前面的内网ip,并获取开放的端口号.D:decoys诱饵
//查看公网ip:curl ident.me
int main(int argc, char **argv) 
{
	int sockfd;
	struct sockaddr_in addr;
	//int dport;
	int on = 1;
	if (argc != 3) 
	{
		printf("usage: <command_name> <target_ip> <port>\n");
		exit(-1);
	}
	bzero(&addr, sizeof(struct sockaddr_in));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(atoi(argv[2]));
	//addr.sin_addr.s_addr=inet_aton(argv[1]);
	inet_pton(AF_INET, argv[1], &addr.sin_addr);
	/*if(inet_aton(argv[1],&addr.sin_addr)==0){
	 * 	host=gethostbyname
	 * 		}*/
	sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);//SOCK_RAW原始套接字,root才可以创建
	if (sockfd<0) 
	{
		printf("Socket error!\n");
		exit(-1);
	}
	setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));//IP_HDRINCL自己编写ip头
	struct timeval tv,tm;
	gettimeofday(&tv,NULL);
	while (1) 
	{
		static int i = 0;
		++i;
		//if(i=5) break;
		send_tcp(sockfd, &addr);
		sleep(1024);
		//gettimeofday(&tm,NULL);
		//if(tv.tv_sec + 10 <= tm.tv_sec) break;
	}
	printf("exit.\n");
	return 0;
}

void send_tcp(int sockfd, struct sockaddr_in *addr) 
{
	char buff[sizeof(struct iphdr) + sizeof(struct tcphdr)];
	memset(buff,0x0,sizeof(buff));
	struct iphdr *ip_header = (struct iphdr *)buff;
	struct tcphdr *tcp_header = (struct tcphdr *)&buff[sizeof(struct iphdr)];
	unsigned short source_port = random_port(1024, 5000);
	char ip_str[50];
	struct in_addr ip;

	//random_ip(ip_str);
	//if (inet_aton(ip_str, &ip) == 0) 
	//{
	//	printf("inet_aton error!\n");
	//	exit(1);
	//}
	ip.s_addr = inet_addr("192.168.0.69");

	//网络层IP
	//ip_header=(struct iphdr*)buff;
	//31                                     0
	//|----|----|------|--|-------------------|----------
	//|ver |ihl | -tos | -|    tot_len        |
	//|----|----|------|--|-------------------|
	//|       id          |   frag_off       -|
	//|---------|---------|-------------------|
	//|   ttl   |protocol |    check          | 20 Bytes
	//|---------|---------|-------------------|
	//|                saddr                  |
	//|---------------------------------------|
	//|                daddr                  |
	//|---------------------------------------|----------
	//|                                       |
	//|                options                | 40 Bytes
	//|                                       |
	//|---------------------------------------|
	//				图:IPv4头部
	//大对大小对小 小端对齐 little endian
	//高位在低地址,低位在高地址,big endian,也是网络字节序:32bit每次传输8bit共4次
	//先传0~7bit 再8~15 16~23 24~31

	//4bit版本号;IPv4
	ip_header->version = 4;
	//4bit首部长度;以32bit为单位 普通ip数据报无选择项,大小是5。5*32/8=20Bytes.
	ip_header->ihl = sizeof(struct iphdr)/4;//0x45
	//8bit服务类型字段;包含三部分:3bit的优先权子字段(现已忽略),4bitTOS字段,1bit未用(但必须置零).其中4bitTOS字段分别代表最小时延,最大吞吐量,最高可靠性,最小费用(4bit中只能设置其中1bit).如果4bit均为0,则为一般服务.
	ip_header->tos = 0;//0x00
	//16bit总长度字段;以bytes为单位 再利用首部长度,可知道数据报中数据的起始位置和长度.总长度最长65535.
	//一些数据链路(如以太网)会填充一些数据以达到最小长度.尽管以太网最小帧长为46bytes,但ip数据可能更短,此时ip层不知道46bytes中有多少是ip数据报的内容,因此总长度字段是必要内容.
	ip_header->tot_len = htons(sizeof(buff));//0x00 0x2e
	//16bit标识字段;唯一地标识主机发送的数据报.每发送一次报文,通常会id+1
	ip_header->id = htons(random());//0xbe 0x55
	//16bit分段偏移Fragment
	//低13位:
	//高3位:第1位保留,必须0.
	//      第2位是"更多分片"(More Fragment)标志.除了最后一片,其他组成数据报的片都应将该位置1.
	//      第3位是"不分片"(Don't Fragment)标志,
	ip_header->frag_off = 0;//0x00 0x00
	//8bit生存时间段;每经过一个路由-1,每一跳(秒)-1,在路由器排队时间较长时计数器多倍递减.到0时数据报被丢弃并发送ICMP报文通知源主机.值通常为32或64.计数单位为s,因此最大生存期为255s.
	//此特性避免数据报长时间逗留在网络中.
	ip_header->ttl = 0x40;//0x1e
	//8bit协议字段;识别是哪个协议向IP传送数据,或将数据报交给哪个进程.UDP,TCP等.
	ip_header->protocol = IPPROTO_TCP;//0x11
	//16bit首部检验和;用32bit计算;计算公式:ip_header全部统计,包括check;接受时如果check不结果不合法,则ip丢掉该数据报,不生成差错报文,由上层(TCP UDP等)去发现丢失的数据报.
	//发送:将ip首部以16bit为单位统计:0x4500+0x002e+0xbe55+0x0000+0x1e11+0x0000+0xdeb7+0x7ee3+0xc0a8+0x127a=0x35250; 11 0101 0010 0101 0000
	//	   check += (check >> 32)    0101 0010 0101 0011//如果仍有17bit高位,重复
	//	                取反(反码)   1010 1101 1010 1100 得0xadac
	//接受:将ip首部以16bit为单位统计:0x4500+0x002e+0xbe55+0x0000+0x1e11+0xadac+0xdeb7+0x7ee3+0xc0a8+0x127a=3fffc;   11 1111 1111 1111 1100
	//     check += (check >> 32)    1111 1111 1111 1111//如果仍有17bit高位,重复
	//     				取反(反码)   0000 0000 0000 0000 结果为0,说明ip首部合法
	ip_header->check = 0;//0x00 0x00 -->0xad 0xac
	//32bit源ip地址,这里随机生成.在内网环境下,非法ip将被路由抛弃.
	ip_header->saddr = ip.s_addr;//0xde 0xb7 0x7e 0xe3 (222.183.126.227)
	//32bit目的ip地址
	ip_header->daddr = addr->sin_addr.s_addr;//0xc0 0xa8 0x12 0x7a (192.168.18.122)

	//传输层TCP
	//tcp_header=(struct tcphdr*)(buff+sizeof(struct iphdr));
	//     |----------------|----------------|-------------
	//     |     source     |     dest       |
	//     |----------------|----------------|
	//     |               seq               |
	//     |---------------------------------|
	//     |               ack_seq           | 20 Bytes
	//     |----|----|------|----------------|
	//     |doff|res1|      |     window     |
	//     |----|----|------|----------------|
	//     |     check      |     urg_ptr    |
	//     |----------------|----------------|-------------
	//     |             options             | (0~40bytes)
	//     |---------------------------------|  
	//					 图:TCP头部
	//struct tcphdr {
	//	  __be16 source; 
	//	  __be16 dest;
	//    __be32 seq;
	//    __be32 ack_seq;
	//#if defined(__LITTLE_ENDIAN_BITFIELD)
	//    __u16 res1:4,
	//    doff:4,
	//    fin:1,
	//    syn:1,
	//    rst:1,
	//    psh:1,
	//    ack:1,
	//    urg:1,
	//    ece:1, 
	//    cwr:1;
	//#elif defined(__BIG_ENDIAN_BITFIELD)
	//    __u16 doff:4,
	//    res1:4,
	//    cwr:1,
	//    ece:1,
	//    urg:1,
	//    ack:1,
	//    psh:1,
	//    rst:1,
	//    syn:1,
	//    fin:1;
	//#else
	//#error "Adjust your <asm/byteorder.h> defines"
	//#endif 
	//    __be16 window;
	//    __sum16 check;
	//    __be16 urg_ptr;
	//};
	//TCP选项:有就4bytes,无就0bytes.
	//typedef struct _TCP_OPTIONS{
	//  char m_ckind;
	//  char m_cLength;
	//  char m_cContext[32];
	//  }__attribute__((packed))TCP_OPTIONS, *PTCP_OPTIONS;

	//16bit源端口号
	tcp_header->source = htons(source_port);
	//16bit目标端口号
	tcp_header->dest = addr->sin_port;
	//32bit序列号;整个报文中,起始序列号为随机数(for safety),后续的序列号=已接收bit数+起始序列号.
	tcp_header->seq =rand();
	//32bit 期望对方下次发送的seq,表示ack_seq-1及之前的数据都正确收到.在seq达到最大时,便从0开始.
	tcp_header->ack_seq = 0;
	//4bitTCP头部长度;指明了TCP头部包含多少个32bit的字.因为options长度是可变的,tcp头部长度也就跟着变化.最长16*32/8=60bytes.
	tcp_header->doff = sizeof(struct tcphdr) / 4;
	//6bit保留位
	tcp_header->res1 = 0;
	//1bit紧急指针标志位;置为1表示ugr_ptr生效.
	tcp_header->urg = 0;
	//1bit确认信息;置为1表示该报文的ack_seq有效.如果为0,ack_seq将被接收方忽略.
	tcp_header->ack = 0;
	//1bit    push;置为1表示该数据应当立即将数据交给应用程序,而不是缓存到缓冲区.
	tcp_header->psh = 0;
	//1bit重置连接;置为1表示接收端有问题,也可用来拒绝连接请求.接受者应当处理.
	tcp_header->rst = 0;
	//1bit建立连接;此时ack_seq不应生效,因此应该让ack=0.
	tcp_header->syn = 1;
	//1bit释放连接;表示发送方数据传输结束.
	tcp_header->fin = 0;
	//16bit滑动窗口;表示从该报文的seq算起,还能接受多少bytes数据.当window=0时,表示已经收到ack_seq-1个bit的数据,现在还不能接收新报文.可以接收新报文时,再重复发一次该报文,但window != 0.即这是TCP的流量控制,最大65535.
    //窗口指发送方的接收窗口。它告诉对方:从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量。之所以有此限制是因为接收方的数据缓存空间是有限的。它指出现在允许对方发送数据量。由于接收缓存不断变化,因此窗口值也不断变化
	tcp_header->window = htons(65535);
	//16bit检验和;ip检验和只包括ip头部,而TCP/UDP检验和包括伪头部,头部和数据.
	tcp_header->check = 0;
	//16bit紧急指针;记录了该数据在整个数据报中的位置.
	//紧急数据的seq号:该报文的seq+紧急指针urg_ptr-1.因为不包括syn(不知道为什么),因此-1.
	//紧急数据又称带外数据(out-of-band data),但描述不准确,因为它仍然随着普通数据发送,并无特殊待遇.只是让接受端知道,这是紧急数据.
	//紧急数据会被覆盖:如果发送了一个字节紧急数据如下,在紧急数据被发送出去前,又发送一个紧急数据'B',那么'B'将覆盖'A'发送出去.
	//write(fd,'A',1,URG);发送紧急数据A,使紧急指针指向'A'.
	tcp_header->urg_ptr = 0;
    //tcp选项和填充:tcp选项大小:tcp首部长度是4bit,范围是0~15,单位是4bytes.故最高60bytes,减去固定20bytes,选项范围是0~40bytes.填充是为了使选项大小是4bytes的整数倍.

	//TCP伪头部:不应该将tcp/udp校验和归纳于任何层,因为ip实际上tcp不该从ip知道的.96bit的伪头部.能够防止出现路由选择错误.
	//-----------------------------------------
	//|         32bit Source IP address       |
	//-----------------------------------------
	//|         32bit Destination IP addr     |
	//-----------------------------------------
	//|  0   | 8bit Proto| 16bit header length|
	//-----------------------------------------
	//			  图:tcp/udp伪头部
	//send_tcp_segment(&ip_header,&tcp_header,"",0);
	/*struct 
	  {
	  unsigned long saddr;//32bit源ip地址
	  unsigned long daddr;//32bit目的ip地址
	  char mbz;//8bit填充对齐,必须置0
	  char ptcl;//8bitprotocol协议号.(IPPROTO_TCP=6,IPPROTO_UDP=17)
	  unsigned short tcpl;//16bitTCP/UDP头长度(不包含数据部分)
	  }psd_header;*/

#pragma pack(1)
	struct pseudo_header    //needed for checksum calculation
	{
		//伪头部 不发送只校验
		unsigned int source_address;//32bit源ip地址
		unsigned int dest_address;//32bit目的ip地址
		unsigned char placeholder;//8bit填充对齐,必须置0
		unsigned char protocol;//8bitprotocol协议号.(IPPROTO_TCP=6,IPPROTO_UDP=17)
		unsigned short tcp_length;//16bitTCP/UDP头长度(不包含数据部分)
		//头部 随ip发送
		struct tcphdr tcp;
	};
#pragma pack()


	struct pseudo_header psd_header;	

	psd_header.source_address = ip_header->saddr;
	psd_header.dest_address = ip_header->daddr;
	psd_header.placeholder = 0;
	psd_header.protocol = IPPROTO_TCP;
	psd_header.tcp_length = htons(sizeof(struct tcphdr));
	memcpy(&psd_header.tcp,tcp_header,sizeof(struct tcphdr));

    //包括了tcp伪头部 tcp头部 tcp数据.
	tcp_header->check = checksum((unsigned short*)&psd_header, sizeof(psd_header));
	//只包括ip头部.
	ip_header->check = checksum((unsigned short*)buff, (sizeof(int)/sizeof(unsigned short)) * ip_header->ihl);

	ssize_t sentlen = sendto(sockfd, buff, tcp_header->doff * 4 + ip_header->ihl * 4 /*sizeof(buff)*/, 0,
			(struct sockaddr *)addr, sizeof(struct sockaddr_in));
	printf("sentlen:%d,bufflen=%d,tcp/iplen=%d,iplen=%d\n",sentlen,sizeof(buff),tcp_header->doff*4+ip_header->ihl*4,ip_header->ihl*4);
	if(sentlen == -1) perror("sendto");
}

unsigned short checksum(unsigned short *buffer, int size) 
{
	unsigned long cksum = 0;

	//size>1时可以直接以16bit为单位进行累加保存.
	while (size >1) 
	{
		cksum += *buffer++;
		size -= sizeof(unsigned short);
	}

	//最后一个size==1说明有数据剩余小于16bit,累加.
	if (size) cksum += *(unsigned char*)buffer;  //..buffer..size..2......

	//将多出16bit的高位加到低位.
	cksum = (cksum >> 16) + (cksum & 0xffff);
	//可能仍然有高位存在,再次加到低位.
	cksum += (cksum >> 16);

	//取反得到校验和.
	return (unsigned short)(~cksum);

}

unsigned short random_port(unsigned short minport, unsigned short maxport) {
	/*struct time stime;
	 *unsigned seed;
	 *gettime(&stime);
	 *seed=stime.ti_hund*stime.ti_min*stime.ti_hour;
	 * srand(seed);*/
	srand((unsigned)time(NULL));
	return(getrandom(minport, maxport));
}

void random_ip(char *str) {
	int a, b, c, d, i = 0;
	static long j = 0;
	srand((unsigned)time(NULL) + (i++) + (j++));
	a = getrandom(0, 255);
	srand((unsigned)time(NULL) + (i++) + (j++));
	b = getrandom(0, 255);
	srand((unsigned)time(NULL) + (i++) + (j++));
	c = getrandom(0, 255);
	srand((unsigned)time(NULL) + (i++) + (j++));
	d = getrandom(0, 255);
	sprintf(str, "%d.%d.%d.%d", a, b, c, d);
	printf("%s\n", str);
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

tcp/ip 详细解析以及网络层简单的发送syn 的相关文章

  • Android TCP 连接最佳实践

    我正在开发一个需要 TCP 连接到 TCP 服务器的 Android 应用程序 用 Node js 编写 我的 Android TCP 客户端正在工作 可以来回发送消息 我的具体问题是 在 Android 中处理与服务器的 TCP 连接的最
  • 是否可以通过 TCP 连接到正在侦听 3G 网络端口的 iPhone?

    我正在开发一个严重依赖 P2P 的应用程序 但我目前没有任何 SIM 卡可供实验 因此我正在 wifi 网络上进行测试 我想知道 3G 网络上的 iPhone 是否可以连接以及是否需要穿越 NAT 设备 您位于提供商的路由器后面 您的 IP
  • 使用正则表达式查找有效的 IP 地址

    我有以下字符串 text 10 0 0 1 1 but 127 0 0 256 1 1 1 1 我想返回有效的IP地址 所以它应该只返回1 1 1 1自从这里256高于255并且第一个IP编号过多 到目前为止 我有以下内容 但它不适用于0
  • PHP 如何在没有 system() 或 exec() 的情况下 ping 服务器

    我正在尝试 ping 服务器 但我的主机被禁用exec and system 由于安全原因 是否还有其他选项可以让它工作 或者我是否必须要求我的主机启用它们 我得到的错误 警告 出于安全原因 system 已被禁用警告 出于安全原因 exe
  • syn队列和accept队列的混淆

    在阅读TCP源码时 我发现一个困惑的事情 我知道 TCP 在 3 次握手中有两个队列 第一个队列存储服务器收到的连接SYN并发回ACK SYN 我们称之为同步队列 第二个队列存储3WHS成功并建立连接的连接 我们称之为接受队列 但在阅读代码
  • 在Servlet中获取真实的客户端IP [重复]

    这个问题在这里已经有答案了 我在一个简单的问题上遇到了一些麻烦 我会得到HTTPServlet 内的真实客户端 IP 从现在开始我使用 request getRemoteAddr 但现在它返回一个错误的IP 例如 xxx xxx xxx 5
  • PHP 上的多个 TCP 套接字请求

    是否可以使用 PHP 上的套接字服务器接受多个请求 并行 如果可以的话 怎样做 普通的 PHP 脚本无法接收多个请求 但如果你真的计划创建一个套接字服务器 作为 cmdline php 脚本启动 那么是的 这是可能的 调查http pear
  • 为什么我们可以将 sockaddr 转换为 sockaddr_in

    我明白为什么强制转换很有用sockaddr to sockaddr in 但我不明白这怎么可能 据我所知 它们的大小相同sockaddr in添加了sin zero使其大小相同 我想知道编译器如何知道从哪里获取信息sockaddr in如果
  • jQuery JSON 请求得到“200 OK”答案,但没有内容

    我正在使用 jQuery 通过访问者的 IP 地址获取其位置 有一项很棒的服务叫做免费地理IP http freegeoip appspot com 我需要做的就是在 URL 末尾添加 json 或 xml 然后添加 IP 地址 它将返回所
  • C# Socket.receive连续接收0字节且循环中不阻塞

    我正在尝试用 C 编写一个最简单的多线程 TCP 服务器 它接收来自多个客户端的数据 每次连接新客户端时 都会建立套接字连接 并将套接字作为参数传递给新类函数 之后运行 while 循环并接收数据 直到客户端连接为止 这里的问题是 sock
  • 如何在Linux中打开端口[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我已经安装了 Web 应用程序 该应用程序在 RHEL centOS 上的端口 8080 上运行 我只能通过命令行访问该机器 我尝试从我的
  • 我应该害怕使用 UDP 进行客户端/服务器广播通话吗?

    我在过去的两天里阅读了每一篇StackOverflow问题和答案 以及googling当然 关于印地TCP and UDP协议 以便决定在我的用户应用程序和 Windows 服务之间的通信方法中应该使用哪一种 从我目前所看到的来看 UDP是
  • 访问 AWS 上的 Tensorboard

    我正在尝试访问 AWS 上的 Tensorboard 这是我的设置 张量板 tensorboard host 0 0 0 0 logdir train 在端口 6006 上启动 TensorBoard b 39 您可以导航到http 172
  • 如何查找连接到 AF_INET 套接字的客户端的 UID?

    有什么方法或类似的东西ucred for AF UNIX如果是AF INET插座 TCP在我的例子中 找出连接到我的套接字的客户端的UID 还有 proc net tcp但它显示了UID of the creator插座的而不是连接的cli
  • 使用 boost 异步发送和接收自定义数据包?

    我正在尝试使用 boost 异步发送和接收自定义数据包 根据我当前的实现 我有一些问题 tcpclient cpp include tcpclient h include
  • PHP中如何识别服务器IP地址

    PHP中如何识别服务器IP地址 对于服务器 ip 来说是这样的 SERVER SERVER ADDR 这是港口的 SERVER SERVER PORT
  • 当我使用“control-c”关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收“”

    我是套接字编程的新手 我知道使用 control c 关闭套接字是一个坏习惯 但是为什么在我使用 control c 关闭发送进程后 接收方上的套接字不断接收 在 control c 退出进程后 发送方的套接字不应该关闭吗 谢谢 我知道使用
  • 如何抑制Windows防火墙的Windows安全警报?

    当我从这里找到的 ZeroMQ 指南中用 C 创建 Hello World 示例时 http zguide zeromq org page all Ask and Ye Shall Receive http zguide zeromq or
  • Android.system.ErrnoException:isConnected失败:ECONNREFUSED(连接被拒绝)

    我使用Java连接MySQL和Json将数据发送到android 当我通过URL地址将数据从Java发送到json时 http 192 168 1 221 9999 rentalcar service category getAllManu
  • 了解 netty 通道缓冲区和水印

    我正在尝试了解网络缓冲区和水印 作为一个测试用例 我有一个 netty 服务器 它向客户端写入数据 客户端被阻止 基本上每次读取之间有 10 秒的睡眠时间 在正常 I O 下 如果接收方被阻塞 TCP 发送方将受到限制 由于流量控制 发送速

随机推荐

  • tensorflow keras 双向lstm gru的水库水位预测 完整代码+数据 毕业设计

    项目演示 https www bilibili com video BV1RP411f7tn spm id from 333 999 0 0 附完整代码 结果演示
  • 基于STM32单片机水质检测PH值检测电导率TDS检测超声波水位检测

    系统功能设计 末尾附文件 本系统由STM32单片机核心板 超声波测距模块 PH值传感器模块 电导率传感器 LCD1602液晶及电源组成 1 超声波传感器采集探测距离 PH传感器采集PH值 PH传感器需要根据手册校准 电导率传感器采集液体电导
  • 连接远程ssh老是掉线解决办法

    1 问题描述 ssh 连接vps的远程服务器 连接一段时间自动断开 包括正在输入命令 执行命令的情况 开着代理的话特别容易断开 关闭代理有效解决问题 2 解决方法 最合适的方法 打开 sudo vim etc ssh sshd config
  • unity制作血条

    unity制作血条 在hierarchy中create gt UI gt image 重命名为border 将血条框拖入Source Image Set Native Size 防止变形 在Canvas下create empty 命名为He
  • 反编译 APK 的基本步骤

    文章目录 反编译 APK 的基本步骤 1 编写一个简单的安卓 app 2 将 release app apk 解压缩 3 将 classes dex 文件反编译为 jar 文件 4 使用 jd gui 可视化阅读 classes dex2j
  • 测试用例之支付功能测试点整理【建议收擦】

    一 梳理支付的业务流程如下 点击支付 gt 选择支付方式 gt 确认金额 gt 输入密码 gt 成功支付 完成这个流程测试 也就是完成了项目的冒烟测试 然后需要测试针对流程中的每个阶段和步骤 具体分析可能导致异常的测试点 所以我们按阶段和输
  • socket,socket.io,mongodb

    Socket 网络上的程序实现双向的数据链接 这个链接的一端成为socket 1 Socket是一个持久链接 2 Socket是双向通信的 Socket VS ajax轮询 ajax轮询 是利用客户端来发送请求 每隔几秒发送一个http请求
  • elementui 表格中单元格自定义功能

    客户相让表格的可操作空间变得更大 比如说可以修改表格内容 双击之后出现input 点击某一单元格可以弹窗等等 让一切可以需要的功能再单击单元格中实现 其实在elementui的官方文档中也可以找到很详细的说明和demo 但是对于新手前端来说
  • 问题记录:修改NuGet的默认存放位置

    具体流程参考了博主 修改nuget包默认存放路径 但是没找到配置文件 C Users 用户 AppData Roaming NuGet NuGet Config 其他的答案如 C Program Files x86 NuGet Config
  • 移动端页面禁止放大缩小

    安卓 在index html文件中添加meta标签 IOS 在 src app vue 中 script 标签内添加代码
  • [Codeforces] games (R1200) Part.3

    Codeforces games R1200 Part 3 题单 https codeforces com problemset tags games 0 1200 1672A Log Chopping 原题指路 https codefor
  • PhotoShop 之移动选区

    不能使用 移动工具 移动选区 否则会出现剪切的效果 移动后 出现了背景颜色 如下图 移动选区 矩形选框工具 魔棒工具等选区工具都可以移动选区 移动选区的时候 注意选区按钮必须在新选区 水平或垂直移动选区的时候 请注意必须先移动选区再按住Sh
  • 2、基于51单片机智能交流电表抄表OLED屏

    毕设帮助 开题指导 技术解答 有偿 见文末 目录 摘要 一 硬件方案 二 设计功能 三 实物图 四 原理图 五 PCB图 六 程序源码 七 资料包括 摘要 电表表示着人们日常用电的多少 现在每家每户安装的根本上是带有转盘的那种电表 它只能显
  • Vue页面监听 键盘按键

    1 监听方法 监听键盘 keyDown document onkeydown e gt 事件对象兼容 let e1 e event window event arguments callee caller arguments 0 键盘按键判
  • Linux 基础知识

    一 从认识操作系统开始 1 1 操作系统简介 我通过以下四点介绍什么操作系统 操作系统 Operation System 简称OS 是管理计算机硬件与软件资源的程序 是计算机系统的内核与基石 操作系统本质上是运行在计算机上的软件程序 为用户
  • 【状态估计】基于无味卡尔曼滤波模拟倾斜传感器研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及讲解 1 概述 本文包括两部分中的第一部分 第一部分设计
  • VT Msr Hook Syscall

    VT Msr Hook Syscall 什么是系统调用 系统调用是内核提供给应用层的接口 比如在 win10x64 应用层打开一个应用 其实就是 explorer 调用了 CreateProcess 这个函数通过 NTDLL 调用表的 0x
  • 大数据技术——hadoop集群搭建出现的问题

    出现的问题和解决方案 ssh免密出现的问题 解决方法 出现上图的是语法错误 在ssh和 keygen中多了空格 去掉即可 2 ssh免密登录出现的问题 ssh登陆报错 WARNING REMOTE HOST IDENTIFICATION H
  • 区块链的工作原理

    区块链系统由数据层 网络层 共识层 激励层 合约层和应用层组成 其中 数据层封装了底层数据区块以及相关的数据加密和时间戳等基础数据和基本算法 网络层则包括分布式组网机制 数据传播机制和数据验证机制等 共识层主要封装网络节点的各类共识算法 激
  • tcp/ip 详细解析以及网络层简单的发送syn

    利用tcp发送syn 我们可以从网络层进行下发 其实就是组装tcp ip包发送出去 include