socket 中午吃的啥 socket 并发服务器 fork

http://www.cnblogs.com/thinksasa/archive/2013/02/26/2934206.html

 

 

zh.wikipedia.org/wiki/網路插座

作業系統中,通常會為應用程式提供一組應用程式介面(API),稱為插座介面英语:socket API)。應用程式可以通過插座介面,來使用網路插座,以進行資料交換。最早的插座介面來自於4.2 BSD,因此現代常見的插座介面大多源自Berkeley套接字(Berkeley sockets)標準。在插座介面中,以IP地址通訊埠組成插座位址socket address)。遠端的插座位址,以及本地的插座位址完成連線後,再加上使用的协议(protocol),这个五元组(five-element tuple),作为插座對(socket pairs),之後就可以彼此交換資料。例如,再同一台计算机上,TCP协议与UDP协议可以同时使用相同的port而互不干扰。 作業系統根據插座地址,可以決定應該將資料送達特定的行程執行緒。這就像是電話系統中,以電話號碼加上分機號碼,來決定通話對象一般。

 

This example, modeled according to the Berkeley socket interface, sends the string "Hello, world!" via TCP to port 80 of the host with address 1.2.3.4. It illustrates the creation of a socket (getSocket), connecting it to the remote host, sending the string, and finally closing the socket:

 

Socket socket = getSocket(type = "TCP")
connect(socket, address = "1.2.3.4", port = "80")
send(socket, "Hello, world!")
close(socket)

 

en.wikipedia.org/wiki/Network_socket

 

The term "socket" is analogous to physical female connectors, communication between two nodes through a channel being visualized as a cable with two male connectors plugging into sockets at each node. Similarly, the term "port" (another term for a female connector) is used for external endpoints at a node, and the term "socket" is also used for an internal endpoint of local inter-process communication (IPC) (not over a network). However, the analogy is strained, as network communication need not be one-to-one or have a channel.

 

 

 

 

 

 Linux socket通信——并发服务器(fork) - CSDN博客 https://blog.csdn.net/w_z_q/article/details/45243765

 

2015年04月24日 10:52:42 

socket通信——并发服务器(fork)

 

一、迭代服务器和并发服务器

迭代服务器会依次处理客户端的连接 ,只要当前连接的任务没有完成,服务器的进程就会一直被占用,直到任务完成后,服务器关闭这个socket,释放连接。

它的原型可以描述成:

while(1)
{
new_fd = 服务器accept客户端的连接(new_fd = accept(listenfd, XX, XX))
逻辑处理
在这个new_fd上给客户端发送消息
关闭new_fd
}
 
并发服务器则是每有一个客户端的连接请求,则克隆一个自己,去处理请求,自身一直处于监听状态而不会被阻塞。并发服务器的一个简单操作是通过fork函数,建立一个子进程分别服务多个客户端。当一个连接建立时,用于阻塞进程的aceept返回,服务器接着调用fork来创建一个子进程,该子进程通过已连接套接口connfd服务客户,同时需要关闭监听套接口listenfd;而父进程就可以通过监听套接口listenfd来等待另外一个连接,同时该关闭已连接套接口。
1while(1)
2 {
3 connfd= 服务器accept客户端的连接
4 if(是子进程)
5 {
6 首先关闭掉监听listenfd// 因为子进程并不需要监听,它只负责处理逻辑并发消息给客户端
7 处理逻辑发送消息
8 关闭connfd
9 关闭进程
10 }
11else if(是父进程)
12关闭connfd
13 }
值得注意的是,在上述过程中,有几个关闭fd的操作,这对初学者来说很难理解。
fork一个子线程后,貌似是复制了两个socket描述符,其实父子线程是共享connfd和listenfd的。只不过connfd和listenfd的引用计数增加了而已。第6行关闭了listenfd,只是将listenfd的引用计数减1,第12行关闭connfd,同样只是将connfd引用计数减1,并没有断开和客户端的连接。
如果没有第12行,会发生什么??第一,因为可分配的socket描述符是有限的,如果分配了以后不释放,也就是不能回收再利用,也就是总有描述符耗尽的一天。第二,本来把和客户端连接的任务交给子进程以后父进程就可以继续监听并accept下个连接了,但如果父进程不关闭自己跟客户的连接,意思就是这个连接居然永远存在!

 

 

   如下是具体连接过程:

(1)服务器阻塞于accept调用且来自客户的连接请求到达时的客户端与服务器的状态。

 

 

(2)从accept返回后,连接已经在内核中注册,并且新的套接口connfd被创建。这是一个已建起连接的套接口,可以进行数据的读写。

 

 

(3)并发服务器在调用fork之后,listenfd和connfd这两个描述字在父进程以及子进程之间共享(实际为其中一份为copy),各自的引用计数为变成2.

 

 

(4)接下来是由父进程关闭已连接套接口(connfd),由子进程关闭监听套接口(listenfd)。进行这个操作之后,那么就可以让子进程来处理与客户的连接,而父进程可以在监听套接口上再次调用accept来处理下一个客户的连接。

 

 

 

 

posted @ 2016-11-21 13:46  papering  阅读(272)  评论(0编辑  收藏  举报