客户端 socket fd 是怎么传入到服务器端 accept 方法的?

周梦康
  • 8.9k

可能一两句话说不清,关闭了吧。

当客户端链接到服务器端,client socket fd如何传入到accept方法里面去的?
在循环服务器中

accept(lfd, (struct sockaddr *)&clin_addr, &clin_len)

为什么当有客户端连接的时候,客户端的sockaddr_in数据就能会被服务器识别赋值到clin_addr呢?然后传入上面的accept方法。

当有预先分配了很多子进程做accept等待,那么新进来的客户端是如何被主线程分配给这些子线程的呢?

// sockfd 是主线程中监听的套接字
for(i = 0; i < 3; i++){
    pid[i] = fork();
    if(pid[i] == 0)
        handle_fork(sockfd);    
}
...
// 子线程做 accpet 阻塞等待
static void handle_fork(int sockfd){
    int newfd;
    struct sockaddr_in c_addr;
    char buf[BUFLEN];
    socklen_t len;
    time_t now;
    while(1){
        len = sizeof(struct sockaddr);
        accept(sockfd,(struct sockaddr*) &c_addr, &len)
        ...
        close(newfd);
    }
}

如果上面伪代码能否表述清楚,可以看下我做的这个笔记http://mengkang.net/576.html#server02

回复
阅读 3.7k
2 个回答
zonxin
  • 12.1k
✓ 已被采纳

第一次见到这样的代码,想法挺好的,但是我们更倾向于创建线程,节省资源。
简单来说
当进程执行到accept意思是请求返回一个TCP链接的描述符,就是说请求一个资源。如果没有操作系统会挂起这个进程,所以这几个子进程都会挂起。
操作系统会分配一个信号量S(就是一个整数,记录有几个链接)。进程执行到accept的时候各个进程会互斥的执行S=S-1,如果大于等于0就继续执行,否则挂起等待操作系统调度。有链接进来就操作系统会S=S+1,如果S>=0,线程继续执行,否者,从挂起的进程中根据线程优先级和等待的时间从中唤醒一个进程。让进程可以有机会继续执行。

多个进程监听同一个描述符,加入了队列中,每次进来新连接时,唤醒第一个进程处理

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏