网络通信之bind、listen函数简述

/* Give the socket FD the local address ADDR (which is LEN bytes long). */
extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len) __THROW;

参数一:调用socket函数返回的文件描述符

参数二:要绑定的给此描述符的协议地址,此处定义了一个宏,原型是const struct sockaddr *,sockaddr 是一个通用结构体,可以包含多种类型的协议地址,但是也带来了使用不便的影响,后又针对具体的协议,制定了不同的专用结构体,像sockaddr_in、sockaddr_in6等等。

参数三:协议地址的大小

bind系统调用将一个本地的网络运输层地址和插口联系起来。一般来说,作为客户的进程并不关心它的本地地址是什么。在这种情况下,进程在进行通信之前没有必要调用bind;内核会自动为其选择一个本地地址。
服务器进程则总是需要绑定到一个已知的地址上。所以,进程在接受连接(TCP)或接收数据报(UDP)之前必须调用bind,因为客户进程需要同已知的地址建立连接或发送数据报到已知的地址。
插口的外部地址由connect指定或由允许指定外部地址的写调用(sendto或sendmsg)指定。

/* Prepare to accept connections on socket FD.
   N connection requests will be queued before further requests are refused.
   Returns 0 on success, -1 for errors.  */
extern int listen (int __fd, int __n) __THROW;

参数一:调用socket函数返回的文件描述符

参数二:连接队列门限值 ,也就是可处理最大连接数


listen系统调用的功能是通知协议进程准备接收插口上的连接请求,它同时也指定插口上可以排队等待的连接数的门限值。超过门限值时,插口层将拒绝进入的连接请求排队等待。当这种情况出现时,TCP将忽略进入的连接请求。

 

bind()和listen()系统调用都是Server端使用的系统调用,Client端不需要进行主动处理,而是由connect自动指定。

延伸:tsleepwakeup函数

当一个在内核中执行的进程因为得不到内核资源而不能继续执行时,它就调用tsleep等待。tsleep的原型是:
int tsleep(caddr_t chan,int pri,char* mesg,int timeo);
tsleep的第一个参数chan,被称之为等待通道。它标志进程等待的特定资源或事件。许多进程能同时在同一个等待通道上睡眠。
当资源可用或事件出现时,内核调用wakeup,并将等待通道作为唯一的参数传入。wakeup的原型是:
void wakeup(caddr_t chan);
所有等待在该通道上的的进程均被唤醒,并被设置成运行状态。当每一个进程均恢复执行时,内核安排tsleep返回。
当进程被唤醒时,tsleep的第二个参数pri指定被唤醒进程的优先级。pri中还包括几个用于tsleep的可选的控制标志。通过设置pri中的PCATCH标志,当一个信号出现时,tsleep也返回。mesg是一个说明调用tsleep的字符串,它将被放在调用报文或ps的输出中。

因为所有等待在同一等待通道上的进程均被wakeup唤醒,所以我们总是看到在一个循环中调用tsleep。每一个被唤醒的进程在继续执行之前必须检查等待的资源是否可得到,因为另一个被唤醒的进程可能已经先一步得到了资源。如果仍然得不到资源,进程再调用tsleep等待。

 

原文地址:https://www.cnblogs.com/klxs1996/p/12809044.html