进程:
进程间通信:
线程:
day1:
一、网络基础知识:
1、网络体系结构:
osi:应用层,表示层,会话层,传输层,网络层,数据链路层,物理层
tcp/ip:应用层,传输层,网络层,物理层
2、ip地址
A 1.0.0.1 ~ 126.255.255.254
B 127.0.0.1 ~ 191.255.255.254
C 192.0.0.1~ 223.255.255.254
D 224.0.0.1~ 239.255.255.254
E 240.0.0.1.1 ~ 255.255.255.254
3、网络协议
1.网络通用协议(tcp、ip)协议簇
2.行业内部专有协议
自定义协议
4、端口号
作用:用作标识一个应用进程
是一个unsigned int 的整数,表示范围1-65535
1-1023已被著名的协议或程序占用,用户可用:1024~65535
5、字节序
大端序:数据的高字节存放在内存的第地址上
小端序:数据的高字节存放在内存的高地址上
Htonl:将4字节的数据的主机字节序转换为网络字节序
Htons:将2字节的数据的主机字节序转换为网络字节序
网络字节序-->大端字节序
二、基于tcp协议网络的server & client模型
server:socket-->bind-->listen-->accept-->io(read/write & recv/send)
client:socket-->connect-->io
- 创建套接字
int listenFd = socket(AF_INET,SOCK_STREAM,0);
参数1:协议域AF_INET(ipv4协议)
参数2:套接字类型SOCK_STREAM
参数3:需要的其他协议 0--》自动匹配其他必要协议
返回值:失败 -1
成功 标识socket通道的文件描述符>3
- 绑定ip与端口号
struct sockaddr_in sin;
memset(&sin,0,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(SERV_PORT);
sin.sin_addr.s_addr = inet_addr(SERV_IP);
int ret = bind = (listenFd(struct sockaddr *)&sin,sizeof(sin));
参数1:文件描述符 socket的返回值
参数2:表示本机地址信息的结构体指针
参数3:地址结构体的长度
返回值:0 成功 -1 失败
- 设置监听套接字
ret = listen(listenFd,10);
参数1:文件描述符 socket的返回值
参数2:服务端一次最大监听的客户端个数
返回值:0 成功 -1 失败
- 接收客户端的连接
struct sockaddr_in stClient;
socklen_t len = sizeof(struct sockaddr_in);
int connFd = accept(listenFd,(struct sockaddr *)&stClient,&len);
参数1:文件描述符 socket的返回值
参数2:地址信息结构,用来存放接收到的客户端的地址信息
参数3:存放第二个参数大小的变量的地址
返回值:成功 返回新的文件描述符--》标识一个新的socket通道--》用于收发数据
失败 -1
- 收发消息
recv(connFd,buf,sizeof(buf),0);
参数1:新的文件描述符 是accept的返回值
参数2:本地接收buf
参数3:期望接收的字节数
参数4:是否阻塞的接收的标志 0表示阻塞接收
返回值:>0 成功接收到的子节数
-1 失败
6. 连接服务器
send(connFd,buf,sizeof(buf),0);
参数1:文件描述符 socket的返回值
参数2:目标服务器的主机地址信息结构
参数3:第二个参数的长度
返回值:0 成功 -1 失败
day2:
一、基于udp的网络客户端和服务器模型
服务器:socket-->bind--<io(sendto/recvfrom)
客户端:socket-->io
recvfrom
ssize_t recvfrom(int sockfd, void *buf,size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
addrlen);
参数1:文件描述符
参数2:接收buf
参数3:期望接收的字节数
参数4:阻塞或非阻塞标志 0--》阻塞
参数5:用来保存对方地址信息
参数6:参数5的长度的地址
返回值:成功 期望接收到的字节数 失败 -1
ret = recvfrom(iServer,buf,sizeof(buf),0,(struct socketaddr *)&st,&len);
sendto
ssize_t sendto(int sockfd, const void *buf,size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
参数1:文件描述符
参数2:发送buf
参数3:期望发送的字节数
参数4:阻塞或非阻塞标志 0--》阻塞
参数5:用来存放对方地址信息
参数6:参数5的长度
返回值:成功 期望发送的字节数 失败 -1
sendto(iServer,buf,sizeof(buf),0,(struct sockaddr *)&st,len);
二、总结tcp、udp:
tcp是一个可靠的,全双工的。有序的,面向连接的字节流通信的协议。
udp是不可靠的,无连接的全双工的通信协议。
udp不可靠的原因:
非面向链接(没有三次握手)
丢包不重发
错误的包不重发
没有信道拥堵控制
有一个最大传输长度限制
没有严格的校验机制
可靠性:tcp > udp
实时性:tcp < udp
三、常见套接字:
流式套接字(SOCK_STREAM)
数据报套接字(SOCK_DGrAM)
原始套接字(SOCK——RAW)
四、io模型
阻塞io
若要读的数据没有准备好,或要写入的目标没有空间,将会发生读写阻塞
阻塞函数:
优点:一直等待结果,直到等到结果
缺点:如果等待的接收数据的通道坏掉或文件损坏,那么当前进程会一直被挂起
非阻塞io
若要读的数据没有准备好,IO函数返回一个约定的错误值,不阻塞当前进程 ,可以通过循环去多次尝试读取数据。
非阻塞函数:
优点:没有读到数据不阻塞当前进程,而是直接返回,带回一个错误值
io多路复用
1 文件描述符集合表--》文件描述符对应的IO通道是否有数据发生fd_set stFdr;1024bit
2 select 监控 置位--》stFdr
3 对stFdr中的置位情况做判断 0-->fgets 3--》accept 4-->recv/send
int select(int nfds, fd_set *readfds,fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
作用:监控文件描述符对应的IO通道是否有数据发生
参数1:要监控的文件描述符的最大个数
参数2:读文件描述符集合表
参数3:写文件描述符集合表
参数4:异常文件描述符集合表
参数5:超时时间 ,若为NULL,表示将select变成阻塞函数
返回值:成功 有数据发生的通道的个数 失败 -1
server.c
loop:
FD_SET(listenFD,&stFdr);
FD_SET(0,&stFdr);
ret = select(listenFd+1,&stFdr,NULL,NULL,NULL);
if(ret <= 0)
{
goto loop;
}
printf("select ok\n");
if(FD_ISSET(0,&stFdr))
{
memset(buf,0,sizeof(buf));
fgets(buf,sizeof(buf),stdin);
printf("fegts data is %s\n",buf);
}
if(FD_ISSET(3,&stFdr))
{
memset(buf,0,sizeof(buf));
memset(&stClient,0,len);
int connFd = accept(listen,(struct sockaddr *)&stClient,&len);
if(connTd < 0)
{
perror("accept error");
exit(1);
}
printf("accept ok\n");
}
4.异步io