【转】 linux port scan

2023-05-16

https://www.binarytides.com/tcp-syn-portscan-in-c-with-linux-sockets/

Port Scanning searches for open ports on a remote system. The basic logic for a portscanner would be to connect to the port we want to check. If the socket gives a valid connection without any error then the port is open , closed otherwise (or inaccessible, or filtered).

This basic technique is called TCP Connect Port Scanning in which we use something like a loop to connect to ports one by one and check for valid connections on the socket.

But this technique has many drawbacks :

  1. It is slow since it establishes a complete 3 way TCP handshake. It waits for the connect() function to return.
  2. It is detectable. It leaves more logs on the remote system and on any firewall that is running.

TCP-Syn Port scanning is a technique which intends to cure these two problems. The mechanism behind it is the handshaking which takes place while establishing a connection. It sends syn packets and waits for an syn+ack reply. If such a reply is received then the port is open otherwise keep waiting till timeout and report the port as closed. Quite simple! In the TCP connect technique the connect() function sends a ack after receiving syn+ack and this establishes a complete connection. But in Syn scanning the complete connection is not made.

This results in :

  1. Faster scans - Partial TCP handshake is done. Only 2 packets exchanged , syn and syn+ack.
  2. Incomplete connections so less detectable. But modern firewalls are smart enough to log all syn activites. So this technique is more or less detectable to same extent as TCP connect port scanning.

TCP Connect Port Scan looks like :

You -> Send Syn packet -> Host:port
Host -> send syn/ack packet -> You
You -> send ack packet -> Host

... and connection is established

TCP-Syn Port scan looks like

You -> send syn packet ->Host:port
Host -> send syn/ack or rst packet or nothing depending on the port status -> You

... stop and analyse the reply the host send :
If syn+ack reply then port open.
Closed/filtered otherwise.

Results are almost as accurate as that of TCP connection and the scan is much faster.

So the process is :

  1. Send a Syn packet to a port A
  2. Wait for a reply of Syn+Ack till timeout.
  3. Syn+Ack reply means the port is open , Rst packet means port is closed , and otherwise it might be inaccessible or in a filtered state.

Tools

We shall code a TCP-Syn Port scanner on Linux using sockets and posix thread api.
The tools we need are :

  1. Linux system with gcc and posix libraries installed

  2. Wireshark for analysing the packets (Optional : for better understanding).

Program Logic

  1. Take a hostname to scan.
  2. Start a sniffer thread shall sniff all incoming packets and pick up those which are from hostname and are syn+ack packets.
  3. start sending syn packets to ports in a loop. This needs raw sockets
  4. If the sniffer thread receives a syn/ack packet from the host then get the source port of the packet and report the packet as open.
  5. Keep looping as long as you have nothing else to do.
  6. Quit the program if someone is calling you.

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
/
TCP Syn port scanner code in C with Linux Sockets :)
/

include<stdio.h> //printf

include<string.h> //memset

include<stdlib.h> //for exit(0);

include<sys/socket.h>

include<errno.h> //For errno - the error number

include<pthread.h>

include<netdb.h> //hostend

include<arpa/inet.h>

include<netinet/tcp.h> //Provides declarations for tcp header

include<netinet/ip.h> //Provides declarations for ip header

void * receive_ack( void ptr );
void process_packet(unsigned char
, int);
unsigned short csum(unsigned short * , int );
char * hostname_to_ip(char * );
int get_local_ip (char *);

struct pseudo_header //needed for checksum calculation
{
unsigned int source_address;
unsigned int dest_address;
unsigned char placeholder;
unsigned char protocol;
unsigned short tcp_length;

struct tcphdr tcp;

};

struct in_addr dest_ip;

int main(int argc, char *argv[])
{
//Create a raw socket
int s = socket (AF_INET, SOCK_RAW , IPPROTO_TCP);
if(s < 0)
{
printf ("Error creating socket. Error number : %d . Error message : %s \n" , errno , strerror(errno));
exit(0);
}
else
{
printf("Socket created.\n");
}

//Datagram to represent the packet
char datagram[4096];    
 
//IP header
struct iphdr *iph = (struct iphdr *) datagram;
 
//TCP header
struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct ip));
 
struct sockaddr_in  dest;
struct pseudo_header psh;
 
char *target = argv[1];
 
if(argc < 2)
{
    printf("Please specify a hostname \n");
    exit(1);
}
 
if( inet_addr( target ) != -1)
{
    dest_ip.s_addr = inet_addr( target );
}
else
{
    char *ip = hostname_to_ip(target);
    if(ip != NULL)
    {
        printf("%s resolved to %s \n" , target , ip);
        //Convert domain name to IP
        dest_ip.s_addr = inet_addr( hostname_to_ip(target) );
    }
    else
    {
        printf("Unable to resolve hostname : %s" , target);
        exit(1);
    }
}
 
int source_port = 43591;
char source_ip[20];
get_local_ip( source_ip );
 
printf("Local source IP is %s \n" , source_ip);
 
memset (datagram, 0, 4096); /* zero out the buffer */
 
//Fill in the IP Header
iph->ihl = 5;
iph->version = 4;
iph->tos = 0;
iph->tot_len = sizeof (struct ip) + sizeof (struct tcphdr);
iph->id = htons (54321); //Id of this packet
iph->frag_off = htons(16384);
iph->ttl = 64;
iph->protocol = IPPROTO_TCP;
iph->check = 0;      //Set to 0 before calculating checksum
iph->saddr = inet_addr ( source_ip );    //Spoof the source ip address
iph->daddr = dest_ip.s_addr;
 
iph->check = csum ((unsigned short *) datagram, iph->tot_len >> 1);
 
//TCP Header
tcph->source = htons ( source_port );
tcph->dest = htons (80);
tcph->seq = htonl(1105024978);
tcph->ack_seq = 0;
tcph->doff = sizeof(struct tcphdr) / 4;      //Size of tcp header
tcph->fin=0;
tcph->syn=1;
tcph->rst=0;
tcph->psh=0;
tcph->ack=0;
tcph->urg=0;
tcph->window = htons ( 14600 );  // maximum allowed window size
tcph->check = 0; //if you set a checksum to zero, your kernel's IP stack should fill in the correct checksum during transmission
tcph->urg_ptr = 0;
 
//IP_HDRINCL to tell the kernel that headers are included in the packet
int one = 1;
const int *val = &one;
 
if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
{
    printf ("Error setting IP_HDRINCL. Error number : %d . Error message : %s \n" , errno , strerror(errno));
    exit(0);
}
 
printf("Starting sniffer thread...\n");
char *message1 = "Thread 1";
int  iret1;
pthread_t sniffer_thread;

if( pthread_create( &sniffer_thread , NULL ,  receive_ack , (void*) message1) < 0)
{
    printf ("Could not create sniffer thread. Error number : %d . Error message : %s \n" , errno , strerror(errno));
    exit(0);
}

printf("Starting to send syn packets\n");
 
int port;
dest.sin_family = AF_INET;
dest.sin_addr.s_addr = dest_ip.s_addr;
for(port = 1 ; port < 100 ; port++)
{
    tcph->dest = htons ( port );
    tcph->check = 0; // if you set a checksum to zero, your kernel's IP stack should fill in the correct checksum during transmission
     
    psh.source_address = inet_addr( source_ip );
    psh.dest_address = dest.sin_addr.s_addr;
    psh.placeholder = 0;
    psh.protocol = IPPROTO_TCP;
    psh.tcp_length = htons( sizeof(struct tcphdr) );
     
    memcpy(&psh.tcp , tcph , sizeof (struct tcphdr));
     
    tcph->check = csum( (unsigned short*) &psh , sizeof (struct pseudo_header));
     
    //Send the packet
    if ( sendto (s, datagram , sizeof(struct iphdr) + sizeof(struct tcphdr) , 0 , (struct sockaddr *) &dest, sizeof (dest)) < 0)
    {
        printf ("Error sending syn packet. Error number : %d . Error message : %s \n" , errno , strerror(errno));
        exit(0);
    }
}
 
pthread_join( sniffer_thread , NULL);
printf("%d" , iret1);
 
return 0;

}

/
Method to sniff incoming packets and look for Ack replies
/
void * receive_ack( void *ptr )
{
//Start the sniffer thing
start_sniffer();
}

int start_sniffer()
{
int sock_raw;

int saddr_size , data_size;
struct sockaddr saddr;
 
unsigned char *buffer = (unsigned char *)malloc(65536); //Its Big!
 
printf("Sniffer initialising...\n");
fflush(stdout);
 
//Create a raw socket that shall sniff
sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_TCP);
 
if(sock_raw < 0)
{
    printf("Socket Error\n");
    fflush(stdout);
    return 1;
}
 
saddr_size = sizeof saddr;
 
while(1)
{
    //Receive a packet
    data_size = recvfrom(sock_raw , buffer , 65536 , 0 , &saddr , &saddr_size);
     
    if(data_size <0 )
    {
        printf("Recvfrom error , failed to get packets\n");
        fflush(stdout);
        return 1;
    }
     
    //Now process the packet
    process_packet(buffer , data_size);
}
 
close(sock_raw);
printf("Sniffer finished.");
fflush(stdout);
return 0;

}

void process_packet(unsigned char* buffer, int size)
{
//Get the IP Header part of this packet
struct iphdr iph = (struct iphdr)buffer;
struct sockaddr_in source,dest;
unsigned short iphdrlen;

if(iph->protocol == 6)
{
    struct iphdr *iph = (struct iphdr *)buffer;
    iphdrlen = iph->ihl*4;
 
    struct tcphdr *tcph=(struct tcphdr*)(buffer + iphdrlen);
         
    memset(&source, 0, sizeof(source));
    source.sin_addr.s_addr = iph->saddr;
 
    memset(&dest, 0, sizeof(dest));
    dest.sin_addr.s_addr = iph->daddr;
     
    if(tcph->syn == 1 && tcph->ack == 1 && source.sin_addr.s_addr == dest_ip.s_addr )
    {
        printf("Port %d open \n" , ntohs(tcph->source));
        fflush(stdout);
    }
}

}

/
Checksums - IP and TCP
/
unsigned short csum(unsigned short *ptr,int nbytes)
{
register long sum;
unsigned short oddbyte;
register short answer;

sum=0;
while(nbytes>1) {
    sum+=*ptr++;
    nbytes-=2;
}
if(nbytes==1) {
    oddbyte=0;
    *((u_char*)&oddbyte)=*(u_char*)ptr;
    sum+=oddbyte;
}

sum = (sum>>16)+(sum & 0xffff);
sum = sum + (sum>>16);
answer=(short)~sum;
 
return(answer);

}

/
Get ip from domain name
/
char* hostname_to_ip(char * hostname)
{
struct hostent *he;
struct in_addr **addr_list;
int i;

if ( (he = gethostbyname( hostname ) ) == NULL) 
{
    // get the host info
    herror("gethostbyname");
    return NULL;
}

addr_list = (struct in_addr **) he->h_addr_list;
 
for(i = 0; addr_list[i] != NULL; i++) 
{
    //Return the first one;
    return inet_ntoa(*addr_list[i]) ;
}
 
return NULL;

}

/
Get source IP of system , like 192.168.0.6 or 192.168.1.2
/

int get_local_ip ( char * buffer)
{
int sock = socket ( AF_INET, SOCK_DGRAM, 0);

const char* kGoogleDnsIp = "8.8.8.8";
int dns_port = 53;

struct sockaddr_in serv;

memset( &serv, 0, sizeof(serv) );
serv.sin_family = AF_INET;
serv.sin_addr.s_addr = inet_addr(kGoogleDnsIp);
serv.sin_port = htons( dns_port );

int err = connect( sock , (const struct sockaddr*) &serv , sizeof(serv) );

struct sockaddr_in name;
socklen_t namelen = sizeof(name);
err = getsockname(sock, (struct sockaddr*) &name, &namelen);

const char *p = inet_ntop(AF_INET, &name.sin_addr, buffer, 100);

close(sock);

}
Compile and Run

1
$ gcc syn_portscan.c -lpthread -o syn_portscan
-lpthread option is needed to link the posix thread libraries.

Now Run

1
2
3
4
5
6
7
8
9
$ sudo ./syn_portscan www.google.com
Socket created.
www.google.com resolved to 74.125.235.16
Local source IP is 192.168.0.6
Starting sniffer thread...
Starting to send syn packets
Sniffer initialising...
Port 53 open
Port 80 open
Note :

  1. For the program to run correctly the local ip and the hostname ip should be resolved correctly. Wireshark should also show the TCP Syn packets as "Good" and not bogus or something.

  2. The get_local_ip method is used to find the local ip of the machine which is filled in the source ip of packets. For example : 192.168.1.2 if you are on a LAN or 172.x.x.x if you are directly connected to internet. The local source ip value will show this.

  3. The hostname_to_ip function resolves a domain name to its ip address. It uses the gethostbyname method.

Last Updated On : 9th February 2013

转载于:https://www.cnblogs.com/Dennis-mi/articles/8492023.html

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

【转】 linux port scan 的相关文章

  • 从 PL/SQL 调用 shell 脚本,但 shell 以 grid 用户而非 oracle 身份执行

    我正在尝试使用 Runtime getRuntime exec 从 Oracle 数据库内部执行 shell 脚本 在 Red Hat 5 5 上运行的 Oracle 11 2 0 4 EE CREATE OR REPLACE proced
  • 在 Linux 上更快地分叉大型进程?

    在现代 Linux 上达到与 Linux 相同效果的最快 最好的方法是什么 fork execve combo 从一个大的过程 我的问题是进程分叉大约 500MByte 大 并且一个简单的基准测试只能从进程中实现约 50 个分叉 秒 比较最
  • 创建 jar 文件 - 保留文件权限

    我想知道如何创建一个保留其内容的文件权限的 jar 文件 我将源代码和可执行文件打包在一个 jar 文件中 该文件将在使用前提取 人们应该能够通过运行批处理 shell 脚本文件立即运行示例和演示 然后他们应该能够修改源代码并重新编译所有内
  • Android:ANT 构建失败,并显示 google-play-services-lib:“解析为没有项目的 project.properties 文件的路径”

    我正在尝试使用 ANT 构建我的应用程序 但在包含 google play services lib 库项目后 我惨遭失败 Step 1 我在 project properties 文件中设置了对库项目的引用 android library
  • 强制卸载 NFS 安装目录 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案
  • 跟踪 Linux 程序中活跃使用的内存

    我想跟踪各种程序在特定状态下接触了多少内存 例如 假设我有一个图形程序 最小化时 它可能会使用更少的内存 因为它不会重新绘制窗口 这需要读取图像和字体并执行大量库函数 这些对象仍然可以在内存中访问 但实际上并没有被使用 类似的工具top它们
  • 如何检测并找出程序是否陷入死锁?

    这是一道面试题 如何检测并确定程序是否陷入死锁 是否有一些工具可用于在 Linux Unix 系统上执行此操作 我的想法 如果程序没有任何进展并且其状态为运行 则为死锁 但是 其他原因也可能导致此问题 开源工具有valgrind halgr
  • GLIBCXX_3.4.26 未找到在 BeagleBone 上运行交叉编译的程序

    我有以下程序 include
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • 如何在 shell 脚本中并行运行多个实例以提高时间效率[重复]

    这个问题在这里已经有答案了 我正在使用 shell 脚本 它读取 16000 行的输入文件 运行该脚本需要8个多小时 我需要减少它 所以我将其划分为 8 个实例并读取数据 其中我使用 for 循环迭代 8 个文件 并在其中使用 while
  • Android 时钟滴答数 [赫兹]

    关于 proc pid stat 中应用程序的总 CPU 使用率 https stackoverflow com questions 16726779 total cpu usage of an application from proc
  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • 添加要在给定命令中运行的 .env 变量

    我有一个 env 文件 其中包含如下变量 HELLO world SOMETHING nothing 前几天我发现了这个很棒的脚本 它将这些变量放入当前会话中 所以当我运行这样的东西时 cat env grep v xargs node t
  • Linux 内核标识符中前导和尾随下划线的含义是什么?

    我不断遇到一些小约定 比如 KERNEL Are the 在这种情况下 是内核开发人员使用的命名约定 还是以这种方式命名宏的语法特定原因 整个代码中有很多这样的例子 例如 某些函数和变量以 甚至 这有什么具体原因吗 它似乎被广泛使用 我只需
  • CentOS:无法安装 Chromium 浏览器

    我正在尝试在 centOS 6 i 中安装 chromium 以 root 用户身份运行以下命令 cd etc yum repos d wget http repos fedorapeople org repos spot chromium
  • NPTL 和 POSIX 线程有什么区别?

    NPTL 和 POSIX 线程之间的基本区别是什么 这两者是如何演变的 POSIX 线程 pthread 不是一个实现 它是几个函数的 API 规范 纸上的标准 英文 其名称以pthread 以及定义在
  • os.Mkdir 和 os.MkdirAll 权限

    我正在尝试在程序开始时创建一个日志文件 我需要检查是否 log如果不创建目录 则目录存在 然后继续创建日志文件 好吧 我尝试使用os Mkdir 也os MkdirAll 但无论我在第二个参数中输入什么值 我都会得到一个没有权限的锁定文件夹
  • jpegtran 优化而不更改文件名

    我需要优化一些图像 但不更改它们的名称 jpegtran copy none optimize image jpg gt image jpg 但是 这似乎创建了 0 的文件大小 当我对不同的文件名执行此操作时 大小仍然完全相同 怎么样 jp
  • Linux 中什么处理 ping?

    我想覆盖 更改 linux 处理 ping icmp echo 请求数据包的方式 这意味着我想运行自己的服务器来回复传入的 icmp 回显请求或其他 数据包 但为了使其正常工作 我想我需要禁用 Linux 的默认 ping icmp 数据包
  • ubuntu:升级软件(cmake)-版本消歧(本地编译)[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我的机器上安装了 cmake 2 8 0 来自 ubuntu 软件包 二进制文件放置在 usr bin cmake 中 我需要将 cmake 版本至少

随机推荐

  • 关于深度学习中三维矩阵的理解(RGB图像的输入)

    usr bin env python coding utf 8 34 34 34 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 6
  • (目标检测)①数据集的建立(拍摄收集、数据集标注)

    目录 一 拍摄收集 xff08 一 xff09 视频拍摄 xff08 二 xff09 将MP4文件截取出图片 二 数据集标注 1 打开图片所在的文件夹 2 修改输出文件夹 3 图片标注 这一系列的博客将会帮助我自己 xff08 和大家 xf
  • myCobot pro 机械臂(4)正向运动学——改进DH表示法(开发环境:python)

    我只能说 xff0c 写这篇博客太艰难了 一定要沉住耐心 这个型号的机械臂与官方给的手册里面的参数是有出入的 感谢 台大机器人学课程 机器人学之运动学笔记 3 机械臂DH表示法 43 正向运动学 xff08 Forward Kinemati
  • myCobot pro 机械臂(5)Robotics Toolbox for MATLA(开发环境:matlab)

    感谢 机器人工程师进阶之路 xff1a matlab robotics toolbox安装方法 目录 一 matlab robotics toolbox安装方法 二 改进DH法对myCobot进行仿真 一 matlab robotics t
  • myCobot pro 机械臂(6)逆向运动学

    机械臂逆运动学求解常用的方法有几何法 解析法 数值法 从求解的方式和计算的效率上来看 xff0c 几何法和解析法会考虑机械臂结构不同而造成的差异 xff0c 因此对于不同结构的机械臂会有特定的求解方式 通常来说 xff0c 这两种方法具有速
  • STM32开发基础知识入门

    C语言基础 位操作 对基本类型变量可以在位级别进行操作 1 不改变其他位的值的状况下 xff0c 对某几个位进行设值 先对需要设置的位用 amp 操作符进行清零操作 xff0c 然后用 操作符设值 2 移位操作提高代码的可读性 3 取反操作
  • 蜂鸣器实验

    蜂鸣器介绍 这里采用的是有源蜂鸣器 xff0c 有源蜂鸣器自带了振荡电路 xff0c 一通电就会发声 xff1b 无源蜂鸣器则没有自带震荡电路 xff0c 必须外部提供 2 5Khz 左右的方波驱动 xff0c 才能发声 STM32的单个
  • CodeBlocks 20.03版的若干已知问题及其解决方法

    CodeBlocks 20 03在Win10上运行时会出现一些问题 xff0c 我通过搜索网络找到了解决办法 xff0c 下面分享给大家 一 改变编辑器的字体后引发 wxWidgets debug alert A debugging che
  • sumo的简单使用

    sumo简单教程 安装配置环境变量文件配置运行python文件生成真实路网python调用 如果你也对交通仿真感兴趣 xff0c 且是一个小白 xff0c 但是有python基础 xff0c 我想我可以帮到你 安装 首先安装为我们入门的第一
  • Kube-Prometheus Stack监控mysql

    准备环境 mysql 环境可以搭建2个或者一个来进行监控 我这个是搭建了2个一个使用容器启动 xff0c 一个二进制安装如图所示 配置mysql exporter进行采集数据 apiVersion apps v1 span class to
  • Promise

    一 定义 xff1a 所谓Promise xff0c 简单说就是一个容器 xff0c 里面保存着某个未来才会结束的事件 xff08 通常是一个异步操作 xff09 的结果 从语法上说 xff0c Promise 是一个对象 xff0c 从它
  • 全国大学生智能汽车竞赛硬件篇(二)—电磁信号采集部分

    对于智能车硬件的整体框架主要由5部分组成 xff1a 电磁信号采集与处理部分 电机驱动部分 电源管理部分 主控部分 其他部分 xff08 停车模块等 xff09 1 电磁信号采集部分 这一部分对于电磁组别至关重要 xff0c 对与摄像头组别
  • 嵌入式笔试(1)—海康威视试题

    单选 xff08 15题 xff09 第一题 栈简介 栈由操作系统 xff08 编译器 xff09 自动分配释放 xff0c 用于存放函数的参数值 局部变量等 xff0c 其操作方式类似于数据结构中的栈 堆简介 堆由开发人员分配和释放 xf
  • 常用通信协议——IIC详解(全网最全)

    一 IIC 简介 I2C xff08 Inter Integrated Circuit xff09 是内部整合电路的称呼 xff0c 是一种串行通讯总线 xff0c 使用多主从架构 xff0c 由飞利浦公司在1980年为了让主板 嵌入式系统
  • 常用通信协议——IIC协议编程实现

    一 IIC连接实物示意图 二 IIC协议程序编写的要点 xff1a 1 空闲状态 2 开始信号 3 停止信号 4 应答信号 5 数据的有效位 6 数据传输 三 IIC驱动编写 1 硬件准备 此处使用正点原子Mini板STM32F103 xf
  • Linux驱动编程篇(四)——LED驱动(二)LED驱动框架

    为应对多种芯片或开发板适配的LED驱动程序 xff0c 同时减少开发流程 xff0c 故需要在APP 驱动程序 硬件三个部分中添加一个部分 xff0c 用于放置各单板LED驱动程序的公共部分 一 LED驱动程序框架的流程图 二 对于公共部分
  • Linux驱动编程篇(五)——驱动设计的思想(面向对象)(分层)(分离)

    Liunx驱动 61 驱动框架 43 硬件操作 61 61 61 Liunx驱动 61 驱动框架 43 单片机 对于驱动的的框架 xff0c 大体有三种设计思想 xff1a 1 面向对象 xff1b 2 分层 xff1b 3 分离 xff0
  • 嵌入式Android底层开发(一)——安卓开发的整体框架与简述

    一 Android简介 Android是一种基于Linux内核 xff08 不包含GUN组件 xff09 的自由及开放源代码的操作系统 xff0c 主要使用于移动设备 xff0c 如智能手机和平板电脑 xff0c 由美国Google公司和开
  • 旋转矩阵

    关注下方公众号 xff0c 分享硬核知识 作者 小K 出品 公众号 xff1a 小K算法 xff08 ID xff1a xiaok365 xff09 01 故事起源 有这样的一种矩阵 xff0c 从左上角开始 xff0c 顺时针从外向里旋转
  • 【转】 linux port scan

    https www binarytides com tcp syn portscan in c with linux sockets Port Scanning searches for open ports on a remote sys