1.16号网络

udp中使用connect函数(笔试面试题)

1> udp中可以使用connect函数,但是不会产生三次握手

2> udp中一般在服务器端使用connect函数。

3> udp中如果使用的connect函数,那么该服务器将与指定的客户端会建立唯一的通道,其他客户端向该服务器发消息,就不再接收了

4> udp中可以多次使用connect函数,连接不同的客户端进行通信,也可以设置都不连接,需要将sin_family成员设置成AF_UNSPCE再次进行连接函数

5> 当服务器跟某个客户端连接后,就可以像TCP一样完成使用read/write、send/recv函数了

6> UDP中使用connect的好处

提高传输效率:

不连接时:将信息填充到内核 ---> 发送数据 --->清空内核数据 ---> 将信息填充到内核 ---> 发送数据 --->清空内核数据

连接后:将信息填充到内核 ---> 发送数据 ---> 发送数据 ---> 发送数据 ---> 发送数据 ---> 发送数据

提高数据传输的稳定性:

当服务器连接了A客户端后,建立了唯一的通道,其他客户端再发消息就不接受了,不会影响到A客户端与服务器的沟通

如果不连接,可能会存在A客户端向服务器发送消息过程中,B客户端也向服务器发消息

1 循环服务器模型

循环服务器,在单个任务执行时,只有将上一个客户端处理结束后,才能处理下一个客户端,效率较低

2 多进程实现TCP并发服务器

由于一个服务器在同一时间想要处理多个客户端,就需要实现多任务并发执行,目前所学的多任务并发执行操作有多进程和多线程

可以使用多进程完成:思路如下

父进程可以专门用于客户端连接请求,每连接一个客户端,就创建出一个子进程用于跟客户端进行交互

2.1 通信模型

void handler(int signo)
{
    while(waitpid()>0);      //以非阻塞配合信号完成僵尸进程的回收
}

int  main()
{
    //将信号与信号处理函数绑定
    signal(SIGCHLD, handler);
 
    socket();    //创建用于连接的套接字
    bind();           //绑定IP地址和端口号
    listen();           //将套接字设置成被动监听状态
    
     while(1)
     {
         newfd = accept();           //接收客户端连接请求
         fd = fork();           //创建子进程用于通信
         if(pid > 0)
         {
             //父进程中关闭newfd
             close(newfd);         
         } else if(pid == 0)
         {
             close(sfd);          //关闭sfd
             //子进程用于通信
             recv();
             send();
             close(newfd);       
             exit(EXIT_SUCCESS);     //退出子进程  
         }             
     }    
     
      close(sfd);   关闭监听 
    
}

3 多线程实现TCP并发服务器

多线程切换所需要的资源较小,效率较高,所以可以实现使用多线程完成tcp并发服务器

思路:主线程完成对客户端的连接请求,分支线程完成对客户端的交互工作

3.1 通信模型

socket();         //创建套接字
bind();             //必须绑定
listen();            //设置被动监听
while(1)
{
    newfd = accept();            //接收客户端连接请求
    //创建分支线程,用于跟客户端进行交互
    pthread_create(&tid, NULL, deal_cli_msg, &info);
    
    //线程分离
    pthread_detach(tid);
}
//线程处理函数的定义
void *deal_cli_msg(void *arg)
{
    recv();
    send();
    close();
    pthread_exit();
}

你可能感兴趣的:(网络)