大四上实训笔记(物联网与智慧思维)
文章目录:
Day1
Day2
实现菱形的动画输出
Day3
归并排序
Day4
test_1.c:倒序输出
test_2.c:去掉空格
hwork:输入的字符串,去掉重复的字符
Day5
Day6
Day7
Day8
答辩
第一个问题:http中get和post的区别
第二个问题:QT的信号和槽函数
第三个问题:套接字socket
第四个问题:串口
项目:仓库环境智能监测系统
时间过好快啊 ,大四了~
学校校企合作:华清远见实训
实训内容:智能家居
实训时间:讲课两周+项目答辩两周
Day1
Linux下一切皆文件shift + alt + t打开一个终端命令:pwd:显示当前的绝对路径cd:切换路径ls:显示当前目录下的文件及文件夹-a:显示隐藏文件-l:显示详细信息touch:创建文件gedit:编辑器,可以写文件cat:查看文件内容rm:删除文件cp:拷贝文件mkdir:创建一个文件夹rmdir:删除一个空文件夹vim编辑器:vi filename三种模式:命令行模式:复制nyy 粘贴p 剪切ndd 撤销u插入模式:a i o 按下esc退回到命令行模式底行模式:按冒号进入底行模式 w保存 q退出 wq保存并退出gcc编译器:gcc filename 默认生成一个a.out的可执行文件 ./file预处理 -> 编译 -> 汇编 -> 链接gcc filename -o name变量:<存储类型><数据类型> 变量名;存储类型:auto register static externstatic:静态存储修饰局部变量,作用域不变,生命周期延长修饰全局变量,作用域被限制,生命周期不变extern:引用外部定义结构化编程:判断 选择 循环if(表达式){语句块1;}else{语句块2;}选择switchswitch(表达式){case 常量表达式:语句块;case 常量表达式:语句块;case 常量表达式:语句块;default:语句块;}循环:for while() do{}while gotousleep();system("clear");数组:相同类型的集合,一片连续的存储空间声明: <存储类型><数据类型> 数组名[元素个数];存储类型:auto static数据类型:所有元素都是同一类型元素个数:告诉编译器这个数组有多大的空间int array[10];使用:array[元素下标] //元素下标总是从0开始,最大下标为n-1注意:不要越界arr[3];arr[i];arr[2+3];arr[b[i]];字符数组:char a[10];初始化:int arr[5] = {1,2,3,4,5}; //完全初始化int arr[5] = {1,2,3}; //部分初始化,根据初始化数据的个数从第一个空间开始赋值,未初始化到的自动赋值为0int arr[] = {1,2,3,4,5,6}; //编译器根据初始化的个数为数组分配足够大的空间char buf[] = {'h','e','l','l','o'};char buf[] = "hello";字符串处理函数:strlen:求字符串的长度,不包含'\0'strcat:连接两个字符串char *strcat(char *dest, const char *src);返回值:返回dest所表示的地址,为了链式表达strlen(strcat(a,b));strcpy:char *strcpy(char *dest, const char *src);strcmp:int strcmp(const char *s1, const char *s2);返回值:0表示相等1表示前者比后者大-1表示后者比前者大
Day2
touch:表示更新一个时间戳(创建一个新文件)
gedit:一个编辑器
cat:查看文件内容
rm:删除一个文件 rm -rf xxx
cp:拷贝文件 cp 1.txt 2.txt
mv:移动文件 mv 1.txt /xxx/xx
mkdir:创建一个空文件夹
rmdir:删除一个空文件夹vim编辑器:三种模式:{命令行模式:nyy表示复制n行,ndd表示剪切n行,p表示粘贴,u撤销插入模式:从命令行按a、i、o进入插入模式,按esc退回命令行模式底行模式:从命令行按冒号进入,w表示保存,q表示退出,wq}gcc编译器:预处理 编译 汇编 链接gcc filename.c 默认生成一个a.out的可执行文件./a.out执行文件gcc filename.c -o name生成一个叫做name的可执行文件变量:声明格式: <存储类型> <数据类型> 变量名;存储类型:auto registerstatic:修饰局部变量,生命周期延长,作用域不变修饰全局变量,生命周期不变,作用域被限制extern:引用外部定义结构化编程:判断、选择、循环if(表达式){语句块1;}else{语句块2;}if(){语句块;}else if(){语句块;}else{语句块;}选择:switch(表达式){case 常量表达式1:语句块1; break;case 常量表达式2:语句块2; break;case 常量表达式3:语句块3; break;...default :语句块n;}循环:for(表达式1;表达式2;表达式3){循环体;}1、执行表达式12、判断表达式2,为真执行循环体,为假跳出循环3、执行完循环体后执行表达式34、重复第2步while(表达式){循环体;}
实现菱形的动画输出
#include <stdio.h>
#include <unistd.h>int main()
{int i, j, k;for(k = 0; k < 50; k++){for(i = 0; i < 10; i++){for(j = 0; j < 10 - 1 - i + k; j++)printf(" ");for(j = 0; j < 2 * i + 1; j++)printf("*");printf("\n");}for(i = 8; i >= 0; i--){for(j = 0; j < 10 - 1 - i + k; j++)printf(" ");for(j = 0; j < 2 * i + 1; j++)printf("*");printf("\n");}usleep(50000);system("clear");if( k == 49)k = 0;}
}
Day3
数组:{一些相同属性的集合,一片连续的存储空间声明: <存储类型> <数据类型> 数组名[元素个数];int arr[10];使用时,[]里表示元素下标,下标从0开始,n个元素的数组下标最大为n-1注意:使用数组的时候不能够越界,如果越界了可能会产生危险[]里表示下标的时候:a[2+3];a[b];a[b[i]];初始化:int a[6] = {1,2,3,4,5,6}; //完全初始化int a[6] = {1,2}; //部分初始化,会根据初始化的数据个数,从下标0开始依次赋值,未初始化到的编译器赋值0int a[] = {1,2,3,4,5}; //根据初始化个数来给数组开辟刚好合适的空间}字符数组:{char buf[6] = {'h','e','l','l','o'};char buf[] = {"hello"};
}字符串处理函数:{strlen:求字符串的长度(不包含'\0')strcat:连接两个字符串char *strcat(char *dest, const char *src);把src所表示的字符串连接到dest的后面strcpy:char *strcpy(char *dest, const char *src);把src所表示的字符串拷贝到dest里面strcmp:比较两个字符串int strcmp(const char *s1, const char *s2);如果两个字符串一样,返回0如果前者比后者大,返回1如果后者比前者大,返回-1
}
array.c
#include <stdio.h>int main() {int a[10];a[99999] = 100; }
char_arr.c
#include <stdio.h>int main() {char buf[6] = {'h','e','l','l','o'};char buff[] = "hello";for(int i = 0; i < 6; i++)printf("%c", buff[i]);printf("\n"); }
strcat.c
#include <stdio.h> #include <string.h>int main() {char a[100] = "hello ";char b[] = "worldxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";strcat(a, b);printf("%s\n", a); }
strcmp.c
#include <stdio.h> #include <string.h>int main() {char a[] = "abcd";char b[] = "abcd";int cmp = strcmp(a, b);printf("cmp = %d\n", cmp); }
strcpy.c
#include <stdio.h> #include <string.h>int main() {char a[20] = "zaima";char b[] = "o";strcpy(a, b);printf("%s\n", a);for(int i = 0; i < 10; i++)printf("%d ", a[i]);printf("\n"); }
strlen.c
#include <stdio.h> #include <string.h>int main() {char buf[] = "hello";printf("%d\n", sizeof(buf));printf("%d\n", strlen(buf)); }
归并排序
test_1.c:将一个奇数数组和偶数数组合并为一个新的数组,且有序:算法思想——数据结构归并排序
#include <stdio.h>int main() {int a[] = {1,3,5,7,9, 31, 33};int b[] = {2,4,6,8,10,12,14,16,18,20};int n = sizeof(a)/sizeof(int);int m = sizeof(b)/sizeof(int);int c[n+m];int i = 0, j = 0, k = 0;while(i < n && j < m){if(a[i] > b[j])c[k++] = b[j++];elsec[k++] = a[i++];}if( i == n ){while(j < m)c[k++] = b[j++];}if( j == m ){while(i < n)c[k++] = a[i++];}for(i = 0; i < n+m; i++)printf("%d ", c[i]);printf("\n");}
Day4
指针:{内存可以分为多个内存单元,每个内存单元又由一个或多个字节组成,每一个字节都有唯一的编号,这个编号叫地址指针就是地址通常,我们称指针、地址、指针变量 为指针。声明:<存储类型> <数据类型 *> 指针名;int *p;int a;p = &a;*:间接运算符&:取地址符直接运算:通过变量自己得到自己空间的内容间接运算:通过指向变量的指针间接得到变量的内容数据类型可以是void *,表示指向任意类型的指针,要使用任意类型指针的时候,必须强制类型转换野指针:没有指向或者随机指向的指针,容易出现段错误空指针:指向0地址(NULL)的指针,使用的话一定会出现段错误
}指针的运算:{算术运算:++ -- +n p++ : 加上一个p类型的空间,地址往上偏移sizeof(数据类型)p+n :偏移n个空间,地址量的偏移为 + n * sizeof(数据类型)两个指针相加:没有意义指针的乘法、除法也没有意义关系运算:== > < }指针与数组:{数组名就是一个指针 数组名不能改变int arr[10]; int *p = arr;
}int arr[] = {1,2,3,4,5,6,7,8,9};
pointer.c
#include <stdio.h>int main() {int a = 10;int *p;p = &a;printf("%p, %p\n", &a, p);printf("%d, %d\n", a, *p); }
void.c
#include <stdio.h>int main() {void *p;int a = 100;p = &a;printf("%d\n", *(int *)p); }
test_1.c:倒序输出
#include <stdio.h>int main() {int a[] = {1,2,3,4,5,6,7,8,9};int n = sizeof(a)/sizeof(int);int *p, *q, temp;p = a;q = a + n - 1;while(p < q){temp = *p;*p = *q;*q = temp;p++;q--;}for(int i = 0; i < n; i++)printf("%d ", a[i]);printf("\n"); }
test_2.c:去掉空格
#include <stdio.h>int main() {char a[100];gets(a);char *p, *q;p = q = a;while( *p != '\0' ){if( *p != ' ' )*q++ = *p;p++;}*q = '\0';puts(a); }
hwork:输入的字符串,去掉重复的字符
#include <stdio.h>int main() {char buf[100];gets(buf);int flag = 0;char *p, *q, *r;p = q = r = buf;while( *p != '\0' ){flag = 0;q = buf;while( q < r ){if( *q == *p ){flag = 1;break;}elseflag = 0;q++;}if( flag == 0 )*r++ = *p;p++;}*r = '\0';puts(buf); }
Day5
进程:{程序运行一次的过程,也可以叫做资源分配的总称每个进程都是独立的空间,所以进程间切换会耗费很多资源线程:轻量级的进程 -- 同一个进程下的多个线程共享同一个内存空间进程和线程的区别:进程是资源分配的最小单位,线程是任务调度的最小单位
}函数:{一个程序可以分为多个功能模块,每一个功能模块叫做函数声明: <存储类型> <数据类型> 函数名(参数列表);定义: <存储类型> <数据类型> 函数名(参数列表){函数体;返回值;}数据类型:不由函数本身决定,而是由函数的返回值类型决定参数列表:告诉调用者需要传递什么类型的数据返回值:告诉调用者函数执行完的结果int add(int x, int y){int sum = x + y;return sum;}函数的调用:函数名(参数列表);参数列表:叫做实际参数列表,传递具体类型的数据
}函数的参数传递方式:{按值传递:就是拷贝实参的内容到形参空间里,操作的都是实参的副本按地址传递:就可以操作实参本身,因为通过地址可以确定唯一的空间}指针函数:void *func(int a);返回一个地址的函数就是指针函数函数指针:可以指向函数的指针void (*ptr)(int a);
func_arguments.c
#include <stdio.h>void swap(int *x, int *y) {int temp = *x;*x = *y;*y = temp; }int main() {int a = 10, b = 15;swap(&a, &b);printf("a = %d, b = %d\n", a, b); }
func_ptr.c
#include <stdio.h>void sister() {printf("姐姐\n"); }void little_sister() {printf("妹妹\n"); }void call( void (*ptr)() ) {//(*ptr)();ptr(); }int main() {call(sister);//sleep(2);call(little_sister); }
pthread.c
#include <stdio.h> #include <pthread.h>void *do_something(void *arg) {printf("I am child\n"); }int main() {pthread_t ath;pthread_create(&ath, NULL, do_something, NULL);printf("I am parent\n");sleep(1); }
Day6
结构:{多个不同类型的集合语法: struct Name{属性1;属性2;...};struct表示后面所跟的名字是结构的类型名结构是抽象的,类似于int要使用必须声明结构体(结构类型对应的实例)struct Name obj; //obj就是结构体实例}要用结构体下面的成员:{成员运算符:.struct Demo{int a;char b;};struct Demo obj;obj.a = 100;
}文件IO:{每一步都是系统调用Linux下一切皆文件打开文件:int open(const char *pathname, int flags, mode_t mode);功能:打开一个文件(站在内核的角度让系统帮我们打开)返回值:成功返回一个文件描述符,失败返回-1 (文件描述符是最小、未被使用的非负整数)pathname:文件的路径及名字flags:主要以 O_RDONLY:只读O_WRONLY:只写O_RDWR:读写O_CREAT:不存在则创建mode:创建这个文件的时候权限是多少 0664读文件:ssize_t read(int fd, void *buf, size_t count);功能:从fd所表示的文件中读取内容返回值:成功返回实际读到的字节数,失败返回-1fd:已经打开的文件描述符buf:缓冲区,从文件里读到的内容存放到缓冲区里count:预计要读的字节数,一定不能超过buf的大小写文件:ssize_t write(int fd, const void *buf, size_t count);功能:往fd里面写内容返回值:成功返回实际写入的字节数,失败返回-1fd:已经打开的文件描述符buf:缓冲区,要写入文件的内容事先存放的地方count:预计要写的字节数,一定不能超过buf的大小关闭文件:close(fd);文件偏移:off_t lseek(int fd, off_t offset, int whence);功能:偏移文件内部的指针返回值:成功返回偏移量。失败返回-1fd:已经打开的文件描述符offset:偏移量(整数往后偏移,负数往前偏移)whence:以什么位置开始偏移SEEK_SET:文件头的位置SEEK_CUR:文件的当前位置SEEK_END:文件末尾的位置
}实现一个拷贝命令 拷贝文件,文件不存在要创建
jpeg.c
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h>int main() {int fd = open("snsd.jpg", O_RDWR);char buf[2];int ret = read(fd, buf, 2);char temp = buf[0];buf[0] = buf[1];buf[1] = temp;lseek(fd, 0, SEEK_SET);write(fd, buf, 2); }
lseek.c
#include <stdio.h> #include <fcntl.h> #include <unistd.h>int main() {int fd = open("kongdong", O_WRONLY | O_CREAT, 0666);char ch = 1;int i = 0;while( i < 1024*4 ){lseek(fd, 1024*1024, SEEK_END);write(fd, &ch, 1);i++;} }
mycp.c
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <string.h>int main(int argc, char *argv[]) {if(argc < 3){printf("you need input %s src_file dest_file\n", argv[0]);return -1;}//打开源文件、要读取内容拷贝到另一个文件int fd_src = open(argv[1], O_RDONLY);if(fd_src < 0){perror("open src");return -1;}//打开目标文件、把源文件的内容拷贝到目标文件int fd_dest = open(argv[2], O_RDWR | O_CREAT, 0666);if(fd_dest < 0){perror("open dest");return -1;}int ret;char buf[64] = {0};while(1){memset(buf, 0, sizeof(buf));//循环读源文件ret = read(fd_src, buf, sizeof(buf));if(ret < 0){perror("Read");return -1;}else if( ret == 0 )break;write(fd_dest, buf, ret);}printf("copy success\n");return 0; }
open.c
#include <stdio.h> #include <fcntl.h> #include <stdlib.h>int main() {int fd = open("9999.txt", O_RDONLY | O_CREAT, 0777);if( fd < 0 ){perror("OPEN");return -1;}printf("Open success, fd = %d\n", fd); }
read.c
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h>int main() {char buf[64];int fd = open("day6.txt", O_RDONLY);if( fd < 0 ){perror("Open");return -1;}printf("Open success\n");int ret = read(fd, buf, sizeof(buf));if( ret < 0 ){perror("Read");return -1;}printf("Read success, ret = %d\n", ret);printf("%s\n", buf); }
write.c
#include <stdio.h> #include <fcntl.h> #include <unistd.h>int main() {int fd = open("9999.txt", O_WRONLY);if( fd < 0 ){perror("open");return -1;}printf("open success\n");char buf[] = "hello 没意思";int ret = write(fd, buf, sizeof(buf));if(ret < 0 ){perror("write");return -1;}printf("ret = %d\n", ret); }
Day7
线程:{轻量级的进程,同一个进程下的不同线程共享同一片空间任务调度的最小单位是线程编译的时候一定要加参数 链接线程库 -lpthread线程创建:int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);功能:创建一个子线程去执行其他任务返回值:成功返回0,失败返回错误码thread:线程对象,方便之后的管理attr:线程属性,默认属性写NULLstart_routine:子线程要去执行的函数arg:要传递给start_routine所指向函数的参数线程管理:线程回收:int pthread_join(pthread_t thread, void **retval);功能:回收子线程的资源返回值:成功返回0,失败返回错误码thread:要回收的线程对象retval:回收子线程结束时传递的信息线程结束:void pthread_exit(void *retval);功能:结束当前线程retval:存放线程结束时携带的信息线程分离:int pthread_detach(pthread_t thread);功能:分离线程retval:要分离的线程对象
}互斥锁:{互斥锁保护某一段代码(临界资源),多个线程都应该能识别这个锁资源,要是全局变量创建互斥锁: 一定要在创建线程之前初始化锁资源int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex‐attr_t *mutexattr);功能:在系统中初始化一个锁资源(1个)返回值:成功返回0,失败返回错误码mutex:锁资源(对象名)mutexattr:互斥锁的属性,默认属性写NULL申请锁:int pthread_mutex_lock(pthread_mutex_t *mutex);功能:申请锁资源,如果没有就阻塞等待,如果申请到了资源才能继续往下执行返回值:成功返回0,失败返回错误码mutex:锁资源(对象名)释放锁:int pthread_mutex_unlock(pthread_mutex_t *mutex);功能:释放锁资源,系统中的锁资源数+1, 其他申请锁的线程可以继续执行返回值:成功返回0,失败返回错误码mutex:锁资源(对象名)
}网络编程:{c/s b/sTCP:有稳定连接,可以检查错误,错误重发,开销大UDP:无连接状态,不能检查错误,不稳定c/s - tcp 模型服务器:socket -> bind -> listen -> accept -> read/write -> close创建套接字:int socket(int domain, int type, int protocol);功能:创建一个套接字(文件描述符)返回值:成功返回创建好的套接字,失败返回-1domain:协议簇,主要用IPv4协议 (AF_INET) --- man 7 iptype:通信模型 主要用TCP模型 (SOCK_STREAM)protocol:额外协议,如果没有就写0绑定套接字:int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);功能:绑定服务器信息返回值:成功返回0,失败返回-1sockfd:已经创建好的套接字addr:包含服务器信息的结构体addrlen:结构体大小监听套接字:接收连接请求:客户端:socket -> connect -> read/write -> close}
mutex.c
#include <stdio.h> #include <pthread.h>int a = 0, b = 0; pthread_mutex_t lock;void *doSomething(void *arg) {while(1){ #ifdef _LOCK_pthread_mutex_lock(&lock); #endifif( a != b ){printf("a = %d, b = %d\n", a, b);} #ifdef _LOCK_pthread_mutex_unlock(&lock); #endif} }int main() {int count = 0;pthread_t ath;pthread_mutex_init(&lock, NULL);pthread_create(&ath, NULL, doSomething, NULL);while(1){count++; #ifdef _LOCK_pthread_mutex_lock(&lock); #endifa = count;b = count; #ifdef _LOCK_pthread_mutex_unlock(&lock); #endif} }
pthread.c
#include <stdio.h> #include <pthread.h>void *doSomething(void *arg) {printf("I am child\n");sleep(5);pthread_exit("我结束了"); }int main() {pthread_t ath;if( 0 != pthread_create(&ath, NULL, doSomething, NULL) ){perror("pthread create");return -1;}printf("I am parent\n");#if 0void *retval;pthread_join(ath, &retval);printf("我的孩子挂掉了\n");printf("孩子说了:%s\n", (char *)retval); #elsepthread_detach(ath); #endif }
socket.c
#include <stdio.h> #include <sys/socket.h>int main() {int sockfd = socket(AF_INET, SOCK_STREAM, 0);if( sockfd < 0 ){perror("socket");return -1;}printf("socket success\n"); }
Day8
服务器:socket -> bind -> listen -> accept -> read/write -> close创建套接字:int socket(int domain, int type, int protocol);功能:创建一个套接字(文件描述符)返回值:成功返回创建好的套接字,失败返回-1domain:协议簇,主要用IPv4协议 (AF_INET) --- man 7 iptype:通信模型 主要用TCP模型 (SOCK_STREAM)protocol:额外协议,如果没有就写0绑定套接字:int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);功能:绑定服务器信息返回值:成功返回0,失败返回-1sockfd:已经创建好的套接字addr:包含服务器信息的结构体addrlen:结构体大小struct sockaddr_in {sa_family_t sin_family; /* address family: AF_INET */in_port_t sin_port; /* port in network byte order */struct in_addr sin_addr; /* internet address */};大端字节序和小端字节序{小端:数据的低字节存放在内存的低地址,高字节存放在高地址大端:数据的低字节存放在内存的高地址,高字节存放在低地址}/* Internet address. */struct in_addr {uint32_t s_addr; /* address in network byte order */};监听套接字:int listen(int sockfd, int backlog);功能:监听已经绑定好的套接字返回值:成功返回0,失败返回-1sockfd:已经绑定好信息的套接字backlog:监听队列大小 2*backlog+1接收连接请求:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);功能:接收客户端的连接请求,并产生一个新的用于通信套接字返回值:成功返回通信套接字,失败返回-1sockfd:已经监听的套接字addr:存放客户端信息的结构体addrlen:结构体大小客户端:socket -> connect -> read/write -> close发起连接请求:int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);功能:主动向服务器发起连接请求返回值:成功返回0,失败返回-1sockfd:已经创建好的套接字addr:包含服务器信息的结构体addrlen:结构体大小
client.c
#include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <string.h> #include <pthread.h>void *send_data(void *arg) {int cfd = (int)arg;char send_buf[64];while(1){memset(send_buf, 0, sizeof(send_buf));gets(send_buf);write(cfd, send_buf, sizeof(send_buf));} }int main() {struct sockaddr_in seraddr;int sfd = socket(AF_INET, SOCK_STREAM, 0);if(sfd < 0){perror("socket");return -1;}seraddr.sin_family = AF_INET;seraddr.sin_port = htons(8888);seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");int ret = connect(sfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if(ret < 0){perror("connect");return -1;}printf("connected successful\n");pthread_t ath;pthread_create(&ath, NULL, send_data, (void *)sfd);char buf[64];while(1){memset(buf, 0, sizeof(buf));read(sfd, buf, sizeof(buf));puts(buf);} }
order.c
#include <stdio.h>int main() {short a = 256;char *p = &a;p++;printf("%d\n", *p); }
server.c
#include <stdio.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <arpa/inet.h> #include <pthread.h>void *recv_data(void *arg) {int cfd = (int)arg;char recv_buf[64];while(1){memset(recv_buf, 0, sizeof(recv_buf));read(cfd, recv_buf, sizeof(recv_buf));puts(recv_buf);} }int main() {struct sockaddr_in servaddr;struct sockaddr_in clitaddr;int sfd = socket(AF_INET, SOCK_STREAM, 0);if(sfd < 0){perror("socket");return -1;}printf("socket success, sfd = %d\n", sfd);int opt = 1;setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(8888);servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");int ret = bind(sfd, (struct sockaddr *)&servaddr, sizeof(servaddr));if( ret < 0 ){perror("bind");return -1;}printf("bind success\n");ret = listen(sfd, 5);if( ret < 0 ){perror("listen");return -1;}printf("listen success\n");socklen_t len = sizeof(clitaddr);int cfd = accept(sfd, (struct sockaddr *)&clitaddr, &len);if(cfd < 0){perror("accept");return -1;}printf("welcome to connected\n");pthread_t ath;pthread_create(&ath, NULL, recv_data, (void *)cfd);char buf[64];while(1){memset(buf, 0, sizeof(buf));gets(buf);write(cfd, buf, sizeof(buf));} }
答辩
第一个问题:http中get和post的区别
HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作1.GET是获取数据,POST是提交数据的2.GET把参数包含在URL中,POST通过request body传递参数2.1 GET:传输数据的时候是在URL地址中的、对所有人都是是可见的、是不安全的;只能传输ASCLL字符,不能进行编码2.2 POST:传输的时候是放在HTTP的请求体之中的,并且是经过urlencode编码的所以是相对安全的;没有对数据类型的限制的,二进制数据也是可以的 2.3 都要进行3次握手,但是说POST是要比GET多进行一次数据传输的,所以GET请求就比POST请求更快
HTTP协议的8种请求类型介绍
第二个问题:QT的信号和槽函数
Qt 信号和槽函数
1.信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性2.当某个信号被发射,就需要调用与之相绑定的槽函数3.信号和槽的机制是类型安全的:一个信号的签名必须与接收槽的签名相匹配4.信号(Signals)当对象改变其状态时,信号就由该对象发射 (emit) 出去,而且对象只负责发送信号,它不知道另一端是谁在接收这个信号信号只需要在头文件中进行声明,不需要在cpp中实现。放在Qt自定义关键字signals下,在此之前一定要加上Q_OBJECT宏5.槽函数(Slots)槽和普通的C++成员函数几乎是一样的(可以是虚函数,可以被重载,可以是public slots、protected slots、private slots,可以被其他C++成员函数直接调用槽还可以和信号连接在一起,在这种情况下,信号被发射时,会自动调用这个槽槽一旦要参数,其参数个数,类型,顺序必须要和对应的信号保持一致。另外,槽的参数不能有缺省值6.关联信号和槽(connect)7.断开信号和槽(disconnect)
第三个问题:套接字socket
套接字
1.套接字Socket=(IP地址:端口号)2.所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程3.是网络编程中的一种通信机制,用来封装 互联网协议(应用层以下的层)4.套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口运用:socket在服务器和客户端的运用创建套接字、绑定套接字、监听套接字、接收连接请求、发起连接请求
第四个问题:串口
串口流程使用 open 函数打开串口设备;设置串口的波特率、数据位、停止位、校验等;使用read/write 函数对串口进行读写操作;串口使用完毕后,使用 close 函数关闭设备串口通讯的特点:双工、半双共、全双工单工 通信:单工通信只有一根数据线,通信只在一个方向上进行这种方式的应用实例有:监视器、打印机、电视机等半双工通信:半双工通信也只有一根数据线,它也单工的区别是这根数据线既可作发送又可作发接收,虽然数据可在两个方向上传送,但通信双方不能同时收发数据全双工通信:数据的发送和接收用两根不同的数据线,通信双方在同一时刻都能进行发送和接收,这一工作方式称为全双工通信在这种方式下,通信双方都有发送器和接收器,发送和接收可同时进行,没有时间延迟串口需不需要映射:需要终端结点 协调结点 那么这个数据的格式是怎么样的终端结点:是客户端请求访问的目标主机,一个终端节点组可以添加1~4个终端节点协调结点:为一种逻辑节点,其中并不保存任何用户数据信息,将请求分发到所需要处理的数据节点
项目:仓库环境智能监测系统
核心服务器端(PC) 数据中心(A9) 远程监控终端(M0)客户端模块:指令下发、环境信息显示、视频监控、处理警报信息 网络编程模块:连通客户端、服务器和信息采集模块的网络 MO数据采集模块:获取温湿度,光照信息,显示实时的视频信息 ZigBee:把采集到的环境参数送给 A9 A9模块:串口通信、实现控制M0模块、数据存储QT:客户端应用程序开发 摄像头:数据采集模块 网络编程 Cortex-A9板开发
大四上实训笔记(物联网与智慧思维)相关推荐
- OSS报表系统实训笔记
OSS报表系统 实训笔记 实训公司:中科天地 (王海格,老师超好) Edited by Hen Egg ,Michelangel ...
- css+js+jq实训笔记
css+js+jq实训笔记 css第一天 css第二天 css第三天 css第四天 css第五天 css第六天 js第一天 js第二天 js第三天 js第四天 js第五天 js第六天 jq第一天 jq ...
- SSM 实训笔记 -10- 使用 sessionStorage 存储数据、js 图片验证码、登录加载动画
SSM 实训笔记 -10- 使用 sessionStorage 存储数据.js 图片验证码.登录加载动画 本篇内容: (1)在登录成功时,使用 sessionStorage 存储用户的用户名,并在登录 ...
- 物联网实训装置-物联网实训平台
产品概述 物联网实训装置是面向中职.高职.本科多层次高校物联网应用专业和物联网实训室建设的实验平台,采用模块化的设计模式,可以根据实际需求选配各种模块组建具有行业特色的物联网工程实训室,与实际应用紧密 ...
- 物联网综合实训平台-物联网实训系统-物联网实训室设备
物联网综合实训平台 产品型号和技术规格 产品特点: 1) 物联网实训工位:设备主体结构必须采用全钢结构,坚固耐用,实训台中央内留显示器安装位置,使整个实训台成为一个整体.外观尺寸1700X1800X3 ...
- 大四软件工程实训 总结 | TMS 物流管理系统 | 我们各自担任了产品经理、项目经理、IT总监、后端、前端和测试
文章目录 一.实训介绍 1.1 实训目的 1.2 角色职责分配 产品经理 项目经理 IT 总监 后端程序员 前端程序员 测试人员 1.3 实训过程 二.实训记录 Day 1 需求文档 Day 2 项目 ...
- 缺项目经验?线上实训机会来咯!!后端企业项目盖章实习,可写进简历
软件行业近十余年得到了飞速的发展,互联网行业的高薪也不断吸引着优秀的人才选择进入软件开发岗位,即便近期整体招聘行情遇冷,但数字化的国家战略不会轻易改变,人才供给速度也仍未赶上技术发展的速度,因此软件开 ...
- 信息安全实训笔记1——身份认证技术
文章目录 实训任务1密码与账户锁定策略 实训任务2 弱口令爆破工具的使用 实训任务3 口令强度判断 实训任务4 明文口令加密 实训任务5 人脸识别技术 总结 实训任务1密码与账户锁定策略 在密码策略中 ...
- 物联网实训笔记_java处理XML文档
DOMTest 读API步骤,先看包,再看类,再读类下面的方法,要注意方法需要的参数和返回值,边用边理解. package com.qiuhu;/*import javax.lang.model.el ...
最新文章
- 触摸矫正+android,android触摸矫正解方程
- 一份整理 | PyTorch是什么,为何选择它
- boost::mpl模块实现find相关的测试程序
- 并不对劲的bzoj5475:loj2983:p5206:[wc2019]数树
- 交易系统高并发下的幂等性设计原则
- python3 正则表达式模块re相关
- 人口简史:我们曾经差一点就彻底没了
- 贴吧用html标签,html标签3(转载)
- Perl中判断数组或hash为空
- Gym 100818I Olympic Parade(位运算)
- Android 12原生设计曝光,Android 12原生设计曝光 网友看了惊呼神似iOS
- c++位运算_最全位运算总结
- HolderView vs ViewHolder实例
- 京东联盟高级API - 高并发京东联盟转链接口 京东客转链接口 京粉转链接口 京东联盟接口,线报无广告接口
- 软件观念革命:交互设计精髓_“被催债”的设计推荐书单
- python爬取二手房信息_使用Scrapy爬取链家二手房信息
- 图像彩色化方法(基于颜色传递、颜色扩展)
- 打开Charles浏览器无法上网
- 计算机研究生哪个子专业最容易考公务员
- 硬盘RAID5后使用的实际容量
热门文章
- 26天备考,安全通过雅思经验帖
- Centos安装Certbot,免费https证书
- c++之静态数据成员与静态成员函数
- BST树遍历O(n)时间复杂度+O(1)空间复杂度
- 最好用的备忘录软件,可用作员工生日提醒,工作事件提醒
- 按位与 逻辑与 按位或| 逻辑或|| 及其应用
- floyd最短路算法的matlab程序,图论之最短路01——最短路矩阵(FLOYD)算法
- 『赠书活动--第二期』清华社赞助 | 《前端系列丛书》
- Docker for windows 入门二(Kitematic的使用)
- oracle键盘不出来,告诉你笔记本键盘没反应怎么解决