本文大部分粘贴自陈同学公众号中的xmind笔记,放上二维码(陈同学在搬砖),给陈同学打call
1.TCP和UDP---传输层的协议
UDP:用户数据报协议,面向无连接,可以单播,多播,广播,面向数据报,不可靠(通信双方不建立连接,数据不会备份,发送方不会关心数据是否到达、UDP没有雍塞控制,无滑窗,网络环境不好一些包可能丢失)用在电话会议
TCP:传输控制协议, 面向连接的,可靠的、基于字节流的,仅支持单播(仅支持点对点传输)可靠性(三次握手、四次挥手)
2.TCP三次握手
select函数:
1.工作之前,需要知道select监管哪些套接字:
2.select开始工作,设定工作时间内开始轮询这些套接字
select工作完成,根据返回值去获知有无就绪,哪些就绪
#include <stdio.h>
#include <netinet/in.h> //for souockaddr_in
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <stdlib.h>
#include <arpa/inet.h>
//for select
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/select.h>
#include <strings.h> //for bzero
#include <string.h>
#define BUFF_SIZE 1024
#define backlog 7
#define ser_port 8000
#define CLI_NUM 3
//创建读写套接字组
int client_fds[CLI_NUM];
int main(int agrc,char **argv)
{
int ser_souck_fd;
int i;
char input_message[BUFF_SIZE];
char resv_message[BUFF_SIZE];
struct sockaddr_in ser_addr;
ser_addr.sin_family= AF_INET; //IPV4
ser_addr.sin_port = htons(ser_port);
ser_addr.sin_addr.s_addr = INADDR_ANY; //指定的是所有地址
//creat socket
//创建监听套接字数组
if( (ser_souck_fd = socket(AF_INET,SOCK_STREAM,0)) < 0 )
{
perror("creat failure");
return -1;
}
//bind soucket
if(bind(ser_souck_fd, (const struct sockaddr *)&ser_addr,sizeof(ser_addr)) < 0)
{
perror("bind failure");
return -1;
}
//listen,监听套接字
if(listen(ser_souck_fd, backlog) < 0)
{
perror("listen failure");
return -1;
}
//fd_set
//创建select监听列表
fd_set ser_fdset;
int max_fd=1;
struct timeval mytime;
printf("wait for client connnect!\n");
while(1)
{
mytime.tv_sec=27;
mytime.tv_usec=0;
//监听列表清零
FD_ZERO(&ser_fdset);
//add standard input
//将fd=0加入fdset,标准输入
FD_SET(0,&ser_fdset);
if(max_fd < 0)
{
max_fd=0;
}
//add serverce
//把文件描述符ser_sourk_fd加入数组,即把文件描述符位的元素置1
FD_SET(ser_souck_fd,&ser_fdset);
if(max_fd < ser_souck_fd)
{
max_fd = ser_souck_fd;
}
//add client