苏嵌实训——day17
文章目录
- 1.1 信号灯集函数接口
- 1.semget
- 2.semctl
- 3.封装初始化函数
- 4. semop
- 二 网络编程
- 2.1 为什么要学习网络编程
- 2.2 发展
- 2.2.1 ARPnet
- 2.2.2 TCP/IP协议
- 2.3 网络体系结构以及OSI开放系统互联模型
- 2.4 TCP/IP协议族
- 2.5 五层模型
- 2.6 TCP和UDP的异同点
- 2.7 函数讲解
- 2.7.1 socket
- 2.7.2 bind()
- 2.7.3 listen
- 2.7.4 accept
- 2.7.5 connect
- 2.8 TCP服务器
- 2.9 TCP客户端
- 2.10 TCP并发服务器
- 2.11 UDP 网络编程
- 函数接口recvfrom/sendto
一 IPC通信之 信号灯集
信号灯集:是在内核空间的信号灯的集合
1.1 信号灯集函数接口
1.semget
头文件:#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>原型:int semget(key_t key, int nsems, int semflg);
功能:创建或者打开一个信号灯集
参数:key:信号灯集的秘钥(和共享内存,消息队列类似)nsems:创建的信号灯集中存在几个信号灯semflg:打开的方式IPC_CREAT:如果共享内存存在,则打开,不存在则创建例如:IPC_CREAT | 0664IPC_EXCL:如果存在则报错返回,如果不存在配合IPC_CREAT创建
返回值:成功返回一个信号灯集的ID失败返回-1
2.semctl
头文件:#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>原型:int semctl(int semid, int semnum, int cmd, ...);
功能:控制信号灯集
参数:semid:要控制的信号灯集的ID号semnum:信号灯的编号cmd:控制方式IPC_RMID:删除信号灯集,不考虑第二个参数GETVAL:获取信号灯的值SETVAL:设置信号灯的值..:可变参数:是一个联合体union semun {int val; /* Value for SETVAL */struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */unsigned short *array; /* Array for GETALL, SETALL */struct seminfo *__buf; /* Buffer for IPC_INFO(Linux-specific) */};
返回值:成功返回 0GETVAL:返回一个信号灯的值失败返回-1
3.封装初始化函数
int sem_init_val(int semid,int semnum,int val)
{union semun myval; //需要自己定义myval.val = val;if(-1 ==semctl(semid,semnum,SETVAL,myval)){printf("初始化信号灯%d失败\n",semnum);return -1; }return 0;
}
4. semop
头文件:#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>原型:int semop(int semid, struct sembuf *sops, size_t nsops);
功能:操作方式
参数:
semid:信号灯集的ID号
sops:操作方法结构体的地址unsigned short sem_num; /* semaphore number */short sem_op; /* semaphore operation */short sem_flg; /* operation flags */使用案例:struct sembuf sops[2];int semid;/* Code to set semid omitted */sops[0].sem_num = 0; /* Operate on semaphore 0 */sops[0].sem_op = 0; /* Wait for value to equal 0 */sops[0].sem_flg = 0;sops[1].sem_num = 0; /* Operate on semaphore 0 */sops[1].sem_op = 1; /* Increment value by one */sops[1].sem_flg = 0;if (semop(semid, sops, 2) == -1) {perror("semop");exit(EXIT_FAILURE);}nsops:同时操作的个数如果说同时操作很多信号灯,填写一个结构体数组
返回值:成功返回0失败返回-1
//write
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
union semun {int val; /* Value for SETVAL */
};
int sem_init_val(int semid,int semnum,int val)
{union semun myval; //需要自己定义myval.val = val;if(-1 ==semctl(semid,semnum,SETVAL,myval)){printf("初始化信号灯%d失败\n",semnum);return -1; }return 0;
}
int sem_p(int semid,int semnum) //参数1:信号灯集 2.信号灯的编号
{ struct sembuf mybuf;mybuf.sem_num = semnum; /* Operate on semaphore 0 */mybuf.sem_op = -1; /* Wait for value to equal 0 */mybuf.sem_flg = 0;if(-1 == semop(semid,&mybuf,1)){printf("p操作失败\n");return -1;}return 0;
}
int sem_v(int semid,int semnum) //参数1:信号灯集 2.信号灯的编号
{ struct sembuf mybuf;mybuf.sem_num = semnum; /* Operate on semaphore 0 */mybuf.sem_op = 1; /* Wait for value to equal 0 */mybuf.sem_flg = 0;if(-1 == semop(semid,&mybuf,1)){printf("v操作失败\n");return -1;}return 0;
}
int main(int argc, char const *argv[])
{//生成一个共享内存使用的key值key_t mykey1 = ftok("/home/jsetc/jsetc/208/",'a');if(-1 == mykey1){perror("生成键值失败");return -1;}//生成一个自定义key值key_t mykey = ftok("/home/jsetc/jsetc/208/day17/",'a');if(-1 == mykey){perror("ftok");return -1;}//创建信号灯集int semid = semget(mykey,2,IPC_CREAT | 0664);if(-1 == semid){perror("semget");return -1;}//初始化信号灯集sem_init_val(semid,0,1);sem_init_val(semid,1,0);//创建共享内存int shmid = shmget(mykey1,4096,IPC_CREAT | 0664);if(-1 == shmid){perror("shmget");return -1;}printf("创建或者打开共享内存成功\n");//地址映射char *buf = (char *)shmat(shmid,NULL,0);if((char *)-1 == buf){perror("shmat");return -1;}while(1){sem_p(semid,0); //p操作printf("请输入\n");scanf("%s",buf);sem_v(semid,1);}return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
union semun {int val; /* Value for SETVAL */
};
int sem_init_val(int semid,int semnum,int val)
{union semun myval; //需要自己定义myval.val = val;if(-1 ==semctl(semid,semnum,SETVAL,myval)){printf("初始化信号灯%d失败\n",semnum);return -1; }return 0;
}
int sem_p(int semid,int semnum) //参数1:信号灯集 2.信号灯的编号
{ struct sembuf mybuf;mybuf.sem_num = semnum; /* Operate on semaphore 0 */mybuf.sem_op = -1; /* Wait for value to equal 0 */mybuf.sem_flg = 0;if(-1 == semop(semid,&mybuf,1)){printf("p操作失败\n");return -1;}return 0;
}
int sem_v(int semid,int semnum) //参数1:信号灯集 2.信号灯的编号
{ struct sembuf mybuf;mybuf.sem_num = semnum; /* Operate on semaphore 0 */mybuf.sem_op = 1; /* Wait for value to equal 0 */mybuf.sem_flg = 0;if(-1 == semop(semid,&mybuf,1)){printf("v操作失败\n");return -1;}return 0;
}
int main(int argc, char const *argv[])
{//生成一个共享内存使用的key值key_t mykey1 = ftok("/home/jsetc/jsetc/208/",'a');if(-1 == mykey1){perror("生成键值失败");return -1;}//生成一个自定义key值key_t mykey = ftok("/home/jsetc/jsetc/208/day17/",'a');if(-1 == mykey){perror("ftok");return -1;}//创建信号灯集int semid = semget(mykey,2,IPC_CREAT | 0664);if(-1 == semid){perror("semget");return -1;}//初始化信号灯集sem_init_val(semid,0,1);sem_init_val(semid,1,0);//创建共享内存int shmid = shmget(mykey1,4096,IPC_CREAT | 0664);if(-1 == shmid){perror("shmget");return -1;}printf("创建或者打开共享内存成功\n");//地址映射char *buf = (char *)shmat(shmid,NULL,0);if((char *)-1 == buf){perror("shmat");return -1;}while(1){sem_p(semid,1); //p操作printf("buf = %s\n",buf);sem_v(semid,0);} return 0;
}
二 网络编程
2.1 为什么要学习网络编程
网络编程就是最后一种进程间通信的方式-----》套接字通信
套接字通信:前六种进程间通信只能实现同一台主机的多个进程通信,但是套接字通信可以实现不同主机的多个进程间通信。
2.2 发展
Arpanet
TCP/IP协议:一共两个协议
网络体系结构:发明了osi开放系统互联模型
TCP/IP协议族:有很多个协议组成
2.2.1 ARPnet
是网络的最早雏形
不能互联不同类型的计算机和不同类型的操作系统,没有纠错功能。
2.2.2 TCP/IP协议
TCP/IP协议分成了两个不同的协议:
用来检测网络传输中差错的传输协议:TCP
专门分则对不同网络进行互联的互联网协议:IP
2.3 网络体系结构以及OSI开放系统互联模型
OSI(国际标准化组织)提供的一个网络体系结构
OSI因为层次结构比较复杂,所以到目前也没有使用,但是他是最早提出的网络体系结构
OSI七层模型:
应用层: 面向用户的,应用程序
表示层:对数据进行加密和解密
会话层:建立逻辑名字和物理名字之间的关系
运输层:用于控制数据的有效传输
网络层:数据分组,路由选择
数据链路层:将数据组成发送或者接收的帧数据
物理层:选择物理介质
注意:每个层次之间的顺序是不能改变的
2.4 TCP/IP协议族
后期基于OSI发明了TCP/IP协议族,这个协议族由很多协议组成:
TCP/IP协议族一共四层:
应用层:telnet,www,FTP,TFTP,SIP
传输层:tcp udp
网络层:IP,ICMP
网络接口与物理层:网卡驱动,物理接口
2.5 五层模型
应用层:
传输层:
网络层:
数据链路层:
物理层:
2.6 TCP和UDP的异同点
相同点:同为传输协议
不同点:TCP是面向连接的,可靠的,基于字节流的传输协议UDP是面向无连接,不可靠的,基于数据报的传输协议
Tcp的概念是一种面向链接的传输协议,它能提供高可靠性的通信(即数据无误,数据不丢失,数据无失序,数据无重复的到达),TCP有回传机制使用情况:适合对于传输质量要求较高,以及传输大量数据的通信,比图MSN/QQ登录,账号管理时需要使用TCP协议
UDP的概念是不可靠的,无连接的传输协议,在数据发送前,因为不需要进行链接,所以可以高效率的数据传输使用情况:适用于对于实时性要求较高的场景,比如:流媒体
2.7 函数讲解
2.7.1 socket
头文件:#include <sys/types.h> /* See NOTES */#include <sys/socket.h>原型:int socket(int domain, int type, int protocol);
功能:创建套接字,返回一个文件描述符
参数:domain:通信域AF_UNIX, AF_LOCAL Local communication unix(7) //本地通信AF_INET IPv4 Internet protocols ip(7) //ipv4网络协议AF_INET6 IPv6 Internet protocols ipv6(7) //ipv6网络协议AF_IPX IPX - Novell protocolsAF_NETLINK Kernel user interface device netlink(7)AF_X25 ITU-T X.25 / ISO-8208 protocol x25(7)AF_AX25 Amateur radio AX.25 protocolAF_ATMPVC Access to raw ATM PVCsAF_APPLETALK AppleTalk ddp(7)AF_PACKET Low level packet interface packet(7) //底层协议通信AF_ALG Interface to kernel crypto APItype:套接字类型SOCK_STREAM :流式套接字 --->tcp SOCK_DGRAM : 数据报套接字 --->udpSOCK_RAW : 原始套接字protocol:附加协议,传0表示不需要其他协议
返回值:成功:文件描述符失败: -1
2.7.2 bind()
头文件:#include <sys/types.h> /* See NOTES */#include <sys/socket.h>原型:int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:将套接字与网络信息结构体绑定
参数:sockfd:文件描述符,socket的返回值addr:网络信息结构体通用结构体:一般不用struct sockaddr {sa_family_t sa_family;char sa_data[14];}网络信息结构体: stuct sockaddr_in{sa_family_t sin_family; //地址族:AF_INETin_port_t sin_port; //网络字节序的端口号struct in_addr sin_addr //ip地址 ---》struct in_addr{uint32_t s_addr; //网络字节序的无符号4字节整数Ip地址 } }addrlen:addr的大小
返回值:成功:返回0失败:返回-1
2.7.3 listen
头文件:#include <sys/types.h> /* See NOTES */#include <sys/socket.h>原型:int listen(int sockfd, int backlog);
功能:将套接字设置为被动监听状态
参数:sockfd:文件描述符,socket的返回值backlog:允许同时连接的客户端的个数,一般设置为5,10
返回值:
成功:0
失败:-1
2.7.4 accept
头文件:#include <sys/types.h> /* See NOTES */#include <sys/socket.h>原型:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:阻塞等待客户端的连接
参数:sockfd:文件描述符,socket的返回值addr:被填充的网络信息结构体,如果由客户端连接服务器,服务器可以通过这个参数获取客户端的信息addrlen:addr的大小
返回值:
成功:返回文件描述符
失败:-1
2.7.5 connect
头文件:#include <sys/types.h> /* See NOTES */#include <sys/socket.h>原型:int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);功能:给服务器发送连接请求
参数:sockfd:文件描述符,socket的返回值addr:要连接的服务器的网络信息结构体,需要客户端自己填充addrlen:addr的大小
返回值:
成功:返回0
失败:-1
2.8 TCP服务器
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include<arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int main(int argc, char const *argv[])
{//创建套接字int sockfd = socket(AF_INET,SOCK_STREAM,0); //IPV4协议,流式套接字,具体的协议类型if(-1 == sockfd){perror("socket");return -1;}struct sockaddr_in server_addr; //保存服务器的信息memset(&server_addr,0,sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8000);server_addr.sin_addr.s_addr = inet_addr("192.168.98.147");//绑定信息int ret = bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));if(-1 == ret){perror("bind");return -1;}//设置监听队列ret = listen(sockfd,10);if(-1 == ret){perror("listen");return -1;}printf("等待客户端进行连接...、\n");struct sockaddr_in Client_addr; //用于保存客户端的信息int length = sizeof(Client_addr);int fd = accept(sockfd,(struct sockaddr *)&Client_addr,&length);if(-1 == fd){perror("accept");return -1;}printf("接收客户端的连接 %d\n",fd);char buf[32] = {0};while(1){ret = recv(fd,buf,sizeof(buf),0);if(-1 == ret){perror("recv");return -1;}if(strcmp(buf,"bye") == 0){break;}printf("%s\n",buf);memset(buf,0 ,sizeof(buf));}close(fd);close(sockfd); return 0;
}
2.9 TCP客户端
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include<arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>int main(int argc, char const *argv[])
{//创建套接字int sockfd = socket(AF_INET,SOCK_STREAM,0);if(sockfd == -1){perror("socket");return -1;}//向服务器发起连接struct sockaddr_in server_addr; //保存服务器的信息memset(&server_addr,0,sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8000);server_addr.sin_addr.s_addr = inet_addr("192.168.98.147");int ret = connect(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));if(-1 == ret){perror("connect");return -1;}char buf[32] = {0};while(1){scanf("%s",buf);ret = send(sockfd,buf,strlen(buf),0);if(-1 == ret){perror("send");return -1;}if(strcmp(buf,"bye") == 0){break;}memset(buf,0,sizeof(buf));}close(sockfd);return 0;
}
2.10 TCP并发服务器
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include<arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <pthread.h>
void * ClientHandler(void *arg)
{int ret;int fd = *(int *)arg;char buf[32] = {0};pthread_detach(pthread_self()); //线程结束,自动释放资源while(1){ret = recv(fd,buf,sizeof(buf),0);if(-1 == ret){perror("recv");return (void *)-1;}else if(0 == ret){break; //客户端异常退出}if(strcmp(buf,"bye") == 0){break;}printf("接收%d客户端 %s\n",fd,buf);memset(buf,0 ,sizeof(buf));}printf("%d 客户端退出!\n",fd);close(fd);
}
int main(int argc, char const *argv[])
{//创建套接字int sockfd = socket(AF_INET,SOCK_STREAM,0); //IPV4协议,流式套接字,具体的协议类型if(-1 == sockfd){perror("socket");return -1;}struct sockaddr_in server_addr; //保存服务器的信息memset(&server_addr,0,sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8000);server_addr.sin_addr.s_addr = inet_addr("192.168.98.147");//绑定信息int ret = bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));if(-1 == ret){perror("bind");return -1;}//设置监听队列ret = listen(sockfd,10);if(-1 == ret){perror("listen");return -1;}printf("等待客户端进行连接...、\n");struct sockaddr_in Client_addr; //用于保存客户端的信息int length = sizeof(Client_addr);while(1){int fd = accept(sockfd,(struct sockaddr *)&Client_addr,&length);if(-1 == fd){perror("accept");return -1;}printf("接收客户端的连接 %d\n",fd);//为每一个客户端创建新的线程pthread_t tid;ret = pthread_create(&tid,NULL,ClientHandler,&fd);if(ret != 0){perror("pthread_create");return -1;}}close(sockfd); return 0;
}
#!/bin/bashfor ((i=0;i<100;i++))
do./4-Tcp客户端 &sleep 0.1
done
练习:实现客户端下载服务器所在目录文件
客户端发送要下载的文件名给服务器
服务器判断文件是否存在,将结果告知客户端
如果文件存在,服务器读取文件内容,并发送给客户端
客户端收到文件内容并写入指定的文件
2.11 UDP 网络编程
服务器:创建套接字 socket填充服务器网络信息结构体将套接字和网络信息结构体绑定bind进行通信 recvfrom /sendto()
客户端:创建套接字 socket填充网络信息结构体进行通信 recvfrom/sendto
函数接口recvfrom/sendto
------recvfrom
1.recvfrom/sendto
------recvfrom
头文件:#include <sys/types.h>#include <sys/socket.h>
原型:ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
功能:接收数据
参数:前四个和recv一样src_addr:源的地址,接收谁的数据,他的信息会自动填充到这个参数addrlen:src_addr的大小
返回值成功:实际接收的字节数失败: 返回-1
------sendto
头文件:#include <sys/types.h>#include <sys/socket.h>
原型:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);功能:接收数据
参数:前四个和send一样dest_addr:目的地址,需要自己指定addrlen:dest_addr的大小
返回值成功:发送的字节数失败: 返回-1
//udp服务器
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#define ERRLOG(errmsg) do{\perror(errmsg);\printf("%s - %s - %d\n",__FILE__,__func__,__LINE__);\exit(1);\}while(0)
int main(int argc, char const *argv[])
{int sockfd;//第一步:创建套接字if(-1 == (sockfd = socket(AF_INET,SOCK_DGRAM,0))){ERRLOG("socket error");}struct sockaddr_in serveraddr,clientaddr;socklen_t addrlen = sizeof(serveraddr);//第二步:填充服务器网络信息结构体 serveraddr.sin_family = AF_INET;serveraddr.sin_addr.s_addr = inet_addr("192.168.98.147");serveraddr.sin_port = 8888;//第三步:将套接字与服务器网路信息结构体绑定int ret = bind(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));if(ret == -1){ERRLOG("bind");}//进行通信char buf[32] = {0};while(1){NEXT:if(recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&clientaddr,&addrlen) == -1){ERRLOG("recvfrom");}if(strcmp(buf,"bye") == 0){printf("客户端%s-%d退出了\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));goto NEXT;}printf("%s-%d: %s\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port),buf);}return 0;
}
//udp客户端
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#define ERRLOG(errmsg) do{\perror(errmsg);\printf("%s - %s - %d\n",__FILE__,__func__,__LINE__);\exit(1);\}while(0)
int main(int argc, char const *argv[])
{int sockfd;//第一步:创建套接字if(-1 == (sockfd = socket(AF_INET,SOCK_DGRAM,0))){ERRLOG("socket error");}struct sockaddr_in serveraddr,clientaddr;socklen_t addrlen = sizeof(serveraddr);//第二步:填充服务器网络信息结构体 serveraddr.sin_family = AF_INET;serveraddr.sin_addr.s_addr = inet_addr("192.168.98.147");serveraddr.sin_port = 8888;//进行通信char buf[32] = {0};while(1){scanf("%s",buf);if(sendto(sockfd,buf,32,0,(struct sockaddr *)&serveraddr,addrlen) == -1){ERRLOG("sendto");}if(strcmp(buf,"bye") == 0){printf("客户端退出了\n");}memset(buf,0,sizeof(buf));}return 0;
}
苏嵌实训——day17相关推荐
- 【苏嵌实训-嵌入式 linux C 第 1天】
| 项目名称 [苏嵌实训-嵌入式 linux C 第 1天] 今日进度以及任务 了解未来就业形势.学习Linux系统开发环境,熟悉编译环境和命令. 任务完成情况 通过在微信公众号及百度搜索完成 本日开 ...
- 苏嵌实训-嵌入式Linux C 第一天
项目名称 苏嵌实训-嵌入式Linux C 第一天 今日进度以及任务 嵌入式开发概述及嵌入式LinuxC项目演示 今日开发中出现的问题汇总 1.嵌入式底层开发为什么选择C语言? 2.什么是实时性?硬实时 ...
- 苏嵌实训——day2
文章目录 一.C语言简单讲解 1.1 代码注释 1.2 中英文切换 1.3 代码讲解 gcc编译出现问题的解决方式 二. 计算机的数据表示 数值型数据 非数值型数据 三.词法符号 3.1 关键词 3. ...
- 苏嵌实训——day7
文章目录 一 Makefile简介 1.1什么是Makefile? 1.2什么是make? 1.3为什么使用? 1.4.优越性 二.makefile 2.1 makfile编译规则 2.2 Makef ...
- 苏嵌实训——day19
文章目录 一.数据库 1.1 在ubuntu中安装数据库 1.2 数据库的操作 1.2.1 数据库命令的分类 1.2.2 常用的系统命令 1.2.3 数据中的常用的语句 1.3 sqlite数据库中常 ...
- 苏嵌实训——day9
文章目录 一 单链表 1.1 概念 1.2 单链表的操作 1.2.1 定义结点结构体 1.2.2 创建一个空的单链表 1.2.3 头插法插入数据 1.2.4 遍历单链表 1.2.5 尾插法插入数据 1 ...
- 苏嵌实训——day18
文章目录 一 wirkeshark 抓包工具 1.1 软件介绍 1.2 软件安装 1.3 wireshark工具的使用 1.4 TCP三次握手和四次挥手 二 TCP循环服务器 2.1 IO多路复用 2 ...
- 苏嵌实训——day11
文章目录 一.队列 1.1 队列的概念 1.2 链式队列 1.2.1 linkqueue.h 1.2.2 linkqueue.c 1.3 顺序队列(循环队列) 1.3.1 sequeue.h 1.3. ...
- 苏嵌实训——day1
文章目录 一.概述 二.Linux 三.linux的系统的层次 四.linux目录结构 五.命令行提示符的介绍 六.linux的基本命令 6.1 ls命令 6.2 chmod命令 6.3 cd 命令 ...
最新文章
- 蓝牙 socket 建立不了_蓝牙电话之PBAP同步电话簿的安卓实现
- 在 aws emr 上,将 hbase table A 的数据,对 key 做 hash,写到另外一张 table B
- 图片上传之后清空_OSS文件上传及OSS与ODPS之间数据连通
- hdu 5124(线段树区间更新+lazy思想)
- 数字图像处理形态学运算
- android 5.0 下载编译
- h5页面生成图片分享到微信js_html2canvas 动态生成微信分享海报的优质js库
- js数字累加 · 递增动画 - 封装篇
- 室内布线电缆未来的发展趋势
- 资产信息自动化收集系统 Venux
- MySQL innodb下的记录锁,间隙锁,next-key锁
- nginx反向代理nexus3
- 2018CUMCM(数学建模国赛)_B——智能RGV的动态调度策略
- 网络地址和广播地址的快速计算方法
- maven 阿里下载源 setting.xml
- 通过经纬度调用百度sdk api实现查询详细地址 Java
- 团队作业——Alpha冲刺 1/12
- Oracle触发器(当A表新增/修改/删除时,同步数据到B表)
- Linux 基础入门 08
- MODBUS通讯详解(博客园)
热门文章
- 解决Redisson无法连接Sentinel, Netty查找DNS失败
- 专为macbook设计的剩余电池电量提醒工具:Battery Indicator
- Java线程安全的有序阻塞队列PriorityBlockingQueue
- Ios 11 android 7,安卓8.0发布同时 苹果的iOS 11 beta 7也来了
- 儿科主治医师总题库 --- 一例APK脱壳反编译寻找AES密钥过程记录
- html的边框阴影的代码是什么,CSS中边框阴影(box-shadow)的实现方法介绍(代码示例)...
- oracle查看谁锁表,ORACLE 如何查询哪个用户锁表?
- !!?用mod删除服务时显示指定服务未安装
- C语言:编写程序,判断某一年是否是闰年
- QT--文字超链接和图片显示