程序编码
__packed
结构体存储到主存储器中时, 为了提高寻址速度往往会将存储体大小与存储单元对其.
在结构体末尾的 __packed 用于告诉编译器在 分配内存时 对结构体进行 不要padding, 可以节省存储空间. 但是由于内存没有对齐, 寻址时还需要进行额外操作, 影响速度.
1 2 3 4 5 6
| struct mgmt_cp_start_service_discovery { uint8_t type; int8_t rssi; uint16_t uuid_count; uint8_t uuids[0][16]; } __packed;
|
new0
这似乎不是C/C++标准的函数,但是见到很多次了就记录一下. 使用new0 可以方便的为某种类型的指针申请空间
1 2
| struct my_struct * pstMyStruct; pstMyStruct = new0(struct my_struct, 1); // 相当于给指针申请了一个结构体空间的大小
|
命令操作
概念知识
why socket
这部分的内容其实比较适合 另外写一篇专题来说, 目前先做个简单的记录。
Socket被广泛用于网络通信, 通过虚拟的链接,A设备中居然可以直接与B进行通信读写,就像B是在A的本地一样。
不过通信嘛! 始终离不开通, 就像之前打电话需要电话线一样。
在打电话的过程中, Socket就像我们手里的手机。我们用户负责听对方讲以及和对方说,而socket(手机)负责将通话内容传递出去。而看不见的”电话线“正是各级路由网络,通话内容根据各级网络的路由一级级传递, 最后依靠IP(电话号码)送达对方Socket(手机)上。
what socket
关于Socket是个啥,其实让我迷惑了好些时候,反正我是分成两个概念来理解的。
首先搞一个背景, 假如一部手机只能给一个号码打电话。
Socket 可以是一个数字(大多0-1024),这个唯一的数字标识了我要找我的老登打电话该用哪部手机。
- Socket是一个专属的文件描述符fd,通过socket函数可以创建一个专属的文件描述符fd,我们t通过这个文件描述符读写数据相当于向网络通信中的对方读写消息。fd托管了我们网络通信的内容
Socket 也是一个四元组组成(本机IP,本机端口,远程IP, 远程端口), 这样就标识了一对关系,本机与远程机的对应关系(可别小看我们之间的羁绊啊阿啊!) 这个四元组也就是这部手机中的电话号码。
- Socket会被要求与一个带有IP地址端口的数据结构bind,这时就确定了四元组的前两元,作为服务端不主动去控制链接,则需要等到对方来链接你时才accept后两元。 如果是客户端负责控制链接那一开始就知道四元组的全部啦~
how socket
好啦自己看!!
Server
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
| #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h>
#define PORT 8080 #define BUFFER_SIZE 1024
int main() { int server_fd, new_socket; struct sockaddr_in address; int addrlen = sizeof(address); char buffer[BUFFER_SIZE] = {0}; // Creating socket file descriptor if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // Forcefully attaching socket to the port 8080 address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); close(server_fd); exit(EXIT_FAILURE); } if (listen(server_fd, 3) < 0) { perror("listen"); close(server_fd); exit(EXIT_FAILURE); } printf("Server listening on port %d\n", PORT); if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { perror("accept"); close(server_fd); exit(EXIT_FAILURE); } int valread = read(new_socket, buffer, BUFFER_SIZE); printf("Message received: %s\n", buffer); close(new_socket); close(server_fd); return 0; }
|
Client
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
| #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h>
#define PORT 8080
int main() { int sock = 0; struct sockaddr_in serv_addr; char *message = "Hello from client"; char buffer[1024] = {0}; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("\n Socket creation error \n"); return -1; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // Convert IPv4 and IPv6 addresses from text to binary form if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { printf("\nInvalid address/ Address not supported \n"); return -1; } if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf("\nConnection Failed \n"); return -1; } send(sock, message, strlen(message), 0); printf("Message sent from client\n"); int valread = read(sock, buffer, 1024); printf("Message from server: %s\n", buffer); close(sock); return 0; }
|