linux C/C++服务器后台开发面试题总结(网络编程篇)

原文链接:https://www.cnblogs.com/nancymake/p/6516933.html

1. TCP头大小,包含字段?三次握手,四次断开描述过程,都有些什么状态。状态变迁图。TCP/IP收发缓冲区(2次)

头部大小是20字节,包含数据如下:

三次握手:

四次释放:

状态变迁图:

收发缓冲区:

2. 使用udp和tcp进程网络传输,为什么tcp能保证包是发送顺序,而 udp无法保证?

因为TCP发送的数据包是按序号发送,有确认机制和丢失重传机制,而udp是不可靠的发送机制,发送的对应端口的数据包不是按顺序发送的。

3. epoll哪些触发模式,有啥区别?(必须非常详尽的解释水平触发和边缘触发的区别,以及边缘触发在编程中要做哪些更多的确认)

epoll有EPOLLLT和EPOLLET两种触发模式,LT是默认的模式,ET是“高速”模式。LT模式下,只要这个fd还有数据可读,每次 epoll_wait都会返回它的事件,提醒用户程序去操作,而在ET(边缘触发)模式中,它只会提示一次,直到下次再有数据流入之前都不会再提示了,无论fd中是否还有数据可读。所以在ET模式下,read一个fd的时候一定要把它的buffer读光,也就是说一直读到read的返回值小于请求值。

也就是说在LT模式的情况下一定要确认收发的数据包的buffer是不是足够大如果收发数据包大小大于buffer的大小的时候就可能会出现数据丢失的情况。

4. tcp与udp的区别(必问)为什么TCP要叫做数据流?

1).基于连接与无连接

2).对系统资源的要求(TCP较多,UDP少)

3).UDP程序结构较简单

4).流模式与数据报模式

5).TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证

6).TCP有拥塞控制和流量控制,UDP没有

TCP提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。

是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快

5.流量控制和拥塞控制的实现机制

网络拥塞现象是指到达通信子网中某一部分的分组数量过多,使得该部分网络来不及处理,以致引起这部分乃至整个网络性能下降的现象,严重时甚至会导致网络通信业务陷入停顿,即出现死锁现象。拥塞控制是处理网络拥塞现象的一种机制。数据的传送与接收过程当中很可能出现收方来不及接收的情况,这时就需要对发方进行控制,以免数据丢失。

6. 滑动窗口的实现机制

滑动窗口机制,窗口的大小并不是固定的而是根据我们之间的链路的带宽的大小,这个时候链路是否拥护塞。接受方是否能处理这么多数据了。 滑动窗口协议,是TCP使用的一种流量控制方法。该协议允许发送方在停止并等待确认前可以连续发送多个分组。由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输。

7.epoll和select的区别?

1)select在一个进程中打开的最大fd是有限制的,由FD_SETSIZE设置,默认值是2048。不过 epoll则没有这个限制,内存越大,fd上限越大,1G内存都能达到大约10w左右。

2)select的轮询机制是系统会去查找每个fd是否数据已准备好,当fd很多的时候,效率当然就直线下降了,epoll采用基于事件的通知方式,一旦某个fd数据就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,高效。

3)select还是epoll都需要内核把FD消息通知给用户空间,epoll是通过内核于用户空间mmap同一块内存实现的,而select则做了不必要的拷贝

8. 网络中,如果客户端突然掉线或者重启,服务器端怎么样才能立刻知道?

若客户端掉线或者重新启动,服务器端会收到复位信号,每一种tcp/ip得实现不一样,控制机制也不一样。

9. TTL是什么?有什么用处,通常那些工具会用到它?ping? traceroute? ifconfig? netstat?

TTL是Time To Live,每经过一个路由就会被减去一,如果它变成0,包会被丢掉。它的主要目的是防止包在有回路的网络上死转,浪费网络资源。ping和traceroute用到它。

10.linux的五种IO模式/异步模式.

1)同步阻塞I/O

2)同步非阻塞I/O

3)同步I/O复用模型

4) 同步信号驱动I/O

5) 异步I/O模型

11. 请说出http协议的优缺点.

1.支持客户/服务器模式。2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径,通信速度很快。3.灵活:HTTP允许传输任意类型的数据对象。4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,导致每次连接传送的数据量增大。缺点就是不够安全,可以使用https完成使用

12.NAT类型,UDP穿透原理。

1)Full cone NAT (全克隆nat):一对一NAT一旦一个内部地址(iAddr:port1)映射到外部地址(eAddr:port2)。

2)Address-Restricted cone NAT(地址受限克隆nat):任意外部主机(hostAddr:any)都能通过给eAddr:port2发包到达iAddr:port1的前提是:iAddr:port1之前发送过包到hostAddr:any. "any"也就是说端口不受限制

3). Port-Restricted cone NAT:内部地址(iAddr:port1)映射到外部地址(eAddr:port2),所有发自iAddr:port1的包都经eAddr:port2向外发送。一个外部主机(hostAddr:port3)能够发包到达iAddr:port1的前提是:iAddr:port1之前发送过包到hostAddr:port3.

4). Symmetric NAT(对称NAT):同内部IP与port的请求到一个特定目的地的IP地址和端口,映射到一个独特的外部来源的IP地址和端口。同一个内部主机发出一个信息包到不同的目的端,不同的映射使用外部主机收到了一封包从一个内部主机可以送一封包回来

13.大规模连接上来,并发模型怎么设计

Epoll+线程池(epoll可以采用libevent处理)

14.tcp三次握手的,accept发生在三次握手哪个阶段?
三次握手:C----->SYN K

          S------>ACK K+1 SYN J

          C------->ACK J+1   

          DONE!

client 的 connect 引起3次握手

server 在socket, bind, listen后,阻塞在accept,三次握手完成后,accept返回一个fd,

16.流量控制与拥塞控制的区别,节点计算机怎样感知网络拥塞了?
拥塞控制是把整体看成一个处理对象的,流量控制是对单个的节点。

感知的手段应该不少,比如在TCP协议里,TCP报文的重传本身就可以作为拥塞的依据。依据这样的原理, 应该可以设计出很多手段。

展开阅读全文

Linux C 网络编程 急~~~~~~~~~~~~~~~~~~

03-19

用多线程实现的的一个多人聊天室....rn用数组储存用户rnstruct userrnrn int id;rn char name[USER_NAME_LEN];rn char password[USER_PASS_LEN];rn char *p_chatlog;rn struct sockaddr user_addr;rn int socket_fd;rn;...rnserver创建了一个监听进程一直accept...rn运行时错误:一个用户登录可以完美操作,程序没任何问题 但是当第二个用户进来 马上server就报recv:socket operation on non-socket...rn我检查了一下,第一个用户进来的时候usr[user_count].socket_fd=5 这是正常的吧..rn第二个用户一进来 第一个用户的socket_fd就变成6了,而第二个用户的socket_fd=0...rn就像请问一下是什么原因造成的...rn这是我的毕业设计,蛋疼死了...纠结了几天了..rn下面是几个相关的函数... 还有 我user_count开始是-1;rn另外里面com_打头的方法是我简单封装了一下的,跟原方法没什么区别的..rn全局变量:rnstruct sockaddr_in server_addr;rnpthread_t listening_thread;rnpthread_t client_thread[MAX_USER_CONN];rnstruct user usr_array[MAX_USER_CONN];rnstruct user usr_list[MAXSIZE];rnint user_list_count;rnint server_fd;rnint user_count=-1;rnrn[code=C/C++]rnint judge_client_action()rnrn int receive_bytes;rn struct message flag_msg;rn bzero(&flag_msg,MSG_LEN);rn printf("usr.socket_fd:%d",usr_array[user_count+1].socket_fd);rn receive_bytes=com_recv(usr_array[user_count+1].socket_fd,&flag_msg,MSG_LEN,0);rn flag_msg.content[receive_bytes]='\0';rn switch(flag_msg.flag)rn rn case 2 : user_login(flag_msg);rn break;rn case 3 : user_regist(flag_msg);rn break;rn default: login_regist_error();rn break;rn rnrnrnvoid pthread_listen()rnrn printf("[INFO]Listening Thread is Strating...\n");rn while(1)rn rn if(listen(server_fd,BACKLOG)==-1) rn rn perror("[ERROR INFO]listen");rn com_exit(1);rn rnrn socklen_t sin_size=sizeof(struct sockaddr_in);rn rn if((usr_array[user_count+1].socket_fd=accept(server_fd,(struct sockaddr*) &usr_array[user_count+1].user_addr,&sin_size))==-1)rn rn perror("[ERROR INFO]socket");rn com_exit(1);rn rn printf("usr_array[user_count+1].socket_fd:%d\n",usr_array[user_count+1].socket_fd);rn printf("[INFO]Some One Connected...\n");rn rn if(pthread_create(&client_thread[user_count+1],NULL,(void *)client_handle,NULL)!=0)rn rn perror("pthread_create listening_thread");rn exit(1);rn rn rnrnrnvoid client_handle()rnrn judge_client_action();rn user_count++;rn struct message msg;rn printf("break point\n");rn strcpy(msg.content,"[INFO]You Are Connected,It's Server's Feed Back...\n");rn com_send(usr_array[user_count].socket_fd,&msg,MSG_LEN,0);rn printf("[INFO]Current User Count:%d\n",user_count+1);rn receive_msg((struct user)usr_array[user_count]);rnrnrnrnvoid receive_msg(struct user r_usr)rnrnwhile(1)rnrn int receive_bytes;rn struct message msg;rn receive_bytes=com_recv(r_usr.socket_fd,&msg,MSG_LEN,0);rn msg.content[receive_bytes]='\0';rn int i=0;rn while(i<=user_count)//send client to clientrn rn com_send(usr_array[i].socket_fd,&msg,MSG_LEN,0);rn i++;rn rnrnrnrnint main()rnrn socket_init();rn init_user_list();rn if((pthread_create(&listening_thread,NULL,(void *)pthread_listen,NULL))!=0)rn rn perror("pthread_create listening_thread");rn exit(1);rn rn //sleep(1);rn printf("[INFO]Current User Count:%d\n",user_count+1);rn while(1)//listening the server message to clientrn rn char send_msg[MAXSIZE];rn scanf("%s",send_msg);rn struct message msg;rn strcpy(msg.content,send_msg);rn int i=0;rn while(i<=user_count)rn rn com_send(usr_array[i].socket_fd,&msg,MSG_LEN,0);rn i++;rn rn rnrnrnrn[/code]rn 论坛

没有更多推荐了,返回首页