一、TCP和UDP可以使用一个端口吗
TCP和UDP可以同时绑定相同的端口
在传输层中,通过端口进行寻址,来识别同一计算机中同时通信的不同应用程序。
TCP和UDP在内核中是两个独立的软件模块,当主机收到数据包后,可以在IP包头的协议号字段知道该数据包是TCP/UDP,根据这个信息确定送给哪个模块。送到模块的报文,再根据其中的端口号来确定送给哪个应用程序处理。
扩展:
1.多个TCP服务进程可以绑定同一个端口吗
如果IP和port都相同,则会bind error。
2.重启TCP服务进程时,为什么会有“Address in use“的报错信息
和四次挥手的关闭连接操作有关,重启TCP服务进程时,服务器端发起了关闭连接操作,因此作为主动关闭方,其会在TIME_WAIT这个状态里停留一段时间,大约2MSL。而TIME_WAIT状态是被视作有效的IP port,因此在bind时报错。
3.客户端的端口可以重复使用吗
TCP连接是由四元组唯一确认的(源IP地址,源端口,目的IP地址,目的端口),即使源IP地址和源端口相同,只要后两者有变化依然可以成功连接而不会导致连接冲突的问题,因此可以重复使用。
二、FTP和HTTP的区别
三、超时重传相关概念说一下(RTO,RTT等)
超时重传
发送端发送报文后若长时间未收到确认的报文则需要重发该报文。可能有以下几种情况:
-
发送的数据没能到达接收端,所以对方没有响应。
-
接收端接收到数据,但是ACK报文在返回过程中丢失。
-
接收端拒绝或丢弃数据
RTO
从上一次发送数据,因为长期没有收到ACK响应,到下一次重发之间的时间。就是重传间隔。
通常每次重传RTO是前一次重传间隔的两倍,计量单位为RTT。
-
RTT:数据从发送到接收到对方响应之间的时间间隔,即数据报在网络中一个往返用时。大小不稳定。
四、说一下慢启动的过程
- 连接建好的开始先初始化拥塞窗口cwnd大小为1,表明可以传一个MSS大小的数据。
- 每当收到一个ACK,cwnd大小加一,呈线性上升。
- 每当过了一个往返延迟时间RTT(Round-Trip Time),cwnd大小直接翻倍,乘以2,呈指数让升。
- 还有一个ssthresh(slow start threshold),是一个上限,当cwnd >= ssthresh时,就会进入“拥塞避免算法”
五、怎么判断有多少端口被占用
例:
netstat 查看端口占用语法格式:
netstat -tunlp | grep 端口号
- -t (tcp) 仅显示tcp相关选项
- -u (udp) 仅显示udp相关选项
- -n 拒绝显示别名,能显示数字的全部转化为数字
- -l 仅列出在Listen(监听)的服务状态
- -p 显示建立相关链接的程序名
六、了解socket编程吗,说一下过程
socket编程的几个函数需要了解
- socket(),为通讯创建一个端点,为套接字返回一个文件描述符。
int socket(int domain, int type, int protocol);
domain为套接字指定协议集,AF_UNIX=AF_LOCAL用于本机进程间通信;AF_INET表示IPv4协议;AF_INET6表示IPv6协议。
type:TCP、UDP等(SOCK_STREAM、SOCK_DGRAM)
protocal:实际使用的传输协议,设为0表示根据domain和type选择缺省协议 - bind()
为套接字分配地址,当使用socket创捷套接字后,是赋予了其使用的协议,并没有分配地址。因此接受其他主机连接之前,必须先调用bind为套接字分配一个地址。int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd 使用bind函数的套接字描述符
addr 指向sockaddr结构的指针
addrlen sockaddr结构的长度 - listen()
socket绑定地址后,默认是想要去连接的,listem会将socket的主动连接的默认属性改为被动连接属性,然后开始监听可能的连接请求。int listen(int sockfd, int backlog);
这只能在使用TCP时使用。
sockfd 使用socket创建的描述符
backlog 监听队列的大小,每当有一个连接请求到来,就会进入此监听队列。当一个请求被accept()接受,这个请求就会被移除对列。当队列满后,新的连接请求就会返回错误,一般发生在同时有大量请求到来,服务器处理不过来的时候。 - connet()
用于TCP连接,为一个套接字设置连接。
sockfd 客户端的socketint connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
addr 服务器端的地址信息
addrlen 服务器端地址信息的大小 - select() poll() epoll()
网络上接受的数据,会先被缓存到内核的页缓冲区,然后将数据从内核空间复制到用户空间。这三个函数均用来实现I/O多路复用
select()int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
nfds:所有文件描述符的范围,即所有文件描述符的最大值+1。可以通过遍历所有listen的fd比较大小来找到最大值
readfds:需要监视那些文件描述符是否可读
writefds:需要监视那些文件描述符是否可写
exceptfds:需要监视哪些文件描述符时候可执行
timeout:等待超时的时间
poll()
poll与select的区别是其没有对最大文件描述符数量的限制。poll和select在每次轮询中,由于要将 大量文件描述的数组在内核空间和用户空间 之间 进行复制,因此开销随着文件描述符数量的增加线性增加。
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
fds pollfd结构体指定了一个被监视的文件描述符,可以通过数组struct pollfd fsd[MAX]传递多个结构体,这样可以使poll()监视多个文件描述符
nfds struct pollfd数组的大小
timeout 超时时间
epoll()
select poll和epoll机制间的比较相同:使用select和poll机制在进行等待时,所在线程都是被移除CPU调度队列的,不会耗费CPU资源的。当等待的事件发生时,线程被唤醒,然后进行事件的处理工作
不同:select和poll的不同主要在与poll没有最大文件描述符的限制,其它基本都相同
当线程被唤醒时,poll()和select()需要轮询所有的描述符,来找到唤醒事件,复杂度为O(n),会随着监听的套接字的个数的增加而线性增加,而epoll会把那个套接字发生了怎样的I/O事件通知我们,复杂度为O(1) - accept()
accept为每个连接建立新的套接字,并从监听队列中移除这个连接。int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
sockefd 监听的套接字描述符
addr 客户端地址结构体信息,一个指向sockaddr的指针
addrlen客户端地址结构体的大小
TCP网络编程:
UDP网络编程
七、算法:有向无环图怎么确定是否有环
拓扑序列,深度优先搜索,三种状态码
Linux相关
参考
socket编程常用函数及参数_socket protocol参数_neverbefat的博客-CSDN博客字节一面:TCP 和 UDP 可以使用同一个端口吗?-tcp端口和udp端口的区别socket编程常用函数及参数_socket protocol参数_neverbefat的博客-CSDN博客