监听套接字 连接套接字

摘要:对于服务器编程中最重要的一步等待并接受客户的连接,那么这一步在编程中如何完成,accept函数就是完成这一步的。它从内核中取出已经建立的客户连接,然后把这个已经建立的连接返回给用户程序,此时用户程序就可以与自己的客户进行点到点的通信了。

accept函数等待并接受客户请求:

#include<sys/socket.h>
int accept(int sockfd, struct sockaddr* addr, socklen_t* len)
返回:非负描述字——成功, -1——失败

accept默认会阻塞进程,直到有一个客户连接建立后返回,它返回的是一个新可用的套接字,这个套接字是连接套接字。此时我们需要区分两种套接
字,一种套接字正如accept的参数sockfd,它是监听套接字,在调用listen函数之后,一个套接字会从主动连接的套接字变身为一个监听套接
字;而accept返回是一个连接套接字,它代表着一个网络已经存在的点点连接。自然要问的是:为什么要有两种套接字?原因很简单,如果使用一个描述字的
话,那么它的功能太多,使得使用很不直观,同时在内核确实产生了一个这样的新的描述字。

参数sockfd
参数sockfd就是上面解释中的监听套接字,这个套接字用来监听一个端口,当有一个客户与服务器连接时,它使用这个一个端口号,而此时这个端口号正与这个套接字关联。当然客户不知道套接字这些细节,它只知道一个地址和一个端口号。

参数addr
这是一个结果参数,它用来接受一个返回值,这返回值指定客户端的地址,当然这个地址是通过某个地址结构来描述的,用户应该知道这一个什么样的地址结构。如果对客户的地址不感兴趣,那么可以把这个值设置为NULL。

参数len
如同大家所认为的,它也是结果的参数,用来接受上述addr的结构的大小的,它指明addr结构所占有的字节个数。同样的,它也可以被设置为NULL。

如果accept成功返回,则服务器与客户已经正确建立连接了,此时服务器通过accept返回的套接字来完成与客户的通信。

这周同学们在做网络编程的时候,碰到一个监听套接字的问题,在这里大概描述一下:

比如我的程序开了一个监听端口,与客户端建立连接之后,生成了一个新套接字。这时我执行了只关闭监听端口的语句,结果却
发现监听端口和已建立的连接仍然存在。我都已经关闭了监听套接字,为什么客户端还可以继续往监听端口发信息?这到底是因为什么呢?新套接字和监听套接字有
什么关系呢?

比如,你开了80监听端口,有一个客户连接你accept了,这时关闭80端口。但此时客户端发信息的时候必然是发向
80断口,但是80已经关了啊,但是通信依然正常进行。其实我刚接触套接字的时候也是认为所有从客户端发来的数据都需要经过监听套接字转一下才能收到。所
有的初学者都容易犯这个误解。

经过一段时间的使用,我现在是明白了,监听套接字就是个牵线指路的,你实质上是跟它指的那个人说话。因为你要找的那个人不可能随时等你来,而监听套接字就是专职等你来问,它回答你要找的人在哪,并唤醒你要找的人,于是通话就建立起来了,就像现实生活中的接线员一样。

也就是说,在连接建立后,客户端用发出连接的那个SOCKET向服务器发数据,是发给服务器新创建的SOCKET,而不是服务器的监听SOCKET。服务器的监听SOCKET永远只是用来接受连接请求。

这就好比你去吃饭,饭馆门口有迎宾小姐(监听SOCKET)看到你来后和你打招呼,然后(ACCEPT)找来一个新的服务员(NEW SOCKET)来接待你,然后守在门口继续监听下一个。监听的小姐走了,接待你的服务员当然不受影响。

说到这里有必要说一下accept()函数。以下是《Linux网络编程》一书,第六章 Berkeley套接字对accept()函数的描述:

函数 accept()有一些难懂。当调用它的时候,大致过程是下面这样的:

● 有人从很远很远的地方尝试调用 connect()来连接你的机器上的某个端口(当然是你已经在 listen()的)。

● 他的连接将被 listen 加入等待队列等待 accept()函数的调用(加入等待队列的最多数目由调用 listen()函数的第二个参数 backlog 来决定)。

● 你调用 accept()函数,告诉他你准备连接。

● accept()函数将回返回一个新的套接字描述符,这个描述符就代表了这个连接!

好,这时候你有了两个套接字描述符,返回给你的那个就是和远程计算机的连接,而第一个套接字描述符仍然在你的机器上原来的那个端口上 listen()。

这时候你所得到的那个新的套接字描述符就可以进行 send()操作和recv()操作了。

通过上面的解释,相信您一定已经对监听套接字有了进一步的了解了吧!

时间: 2024-10-09 14:31:25

监听套接字 连接套接字的相关文章

nginx源码分析--监听套接字的创建 套接字的监听 HTTP请求创建连接

作为一个web服务器,那么肯定是有监听套接字的,这个监听套接字是用于接收HTTP请求的,这个监听套接字的创建是根据配置文件的内容来创建的,在nginx.conf文件中有多少个地址就需要创建多少个监听套接字.这里不说各个结构体的构造 只说大体情况! 1).首先在main函数中调用了ngx_init_cycle()函数,在这个函数的最后调用了ngx_open_listening_sockets函数,这个函数负责将创建的监听套接字进行套接字选项的设置(比如非阻塞.接受发送的缓冲区.绑定.监听处理) 2

oracle的环境配置-监听服务和访问连接原理

监听服务和访问连接原理 端口号范围:1025~6500 [[email protected] ~]$ lsnrctl   --进入监听管理工具 LSNRCTL for Linux: Version 10.2.0.1.0 - Production on 05-JUN-2014 11:13:20 Copyright (c) 1991, 2005, Oracle.  All rights reserved. Welcome to LSNRCTL, type "help" for inform

ora-12514 tns 监听程序无法识别连接描述符中请求的服务

今天,远程连接linux服务器时遇到这样一个错误,tnsnames.ora 和 listener.ora文件配置都没有错误 但是就是连接不上  tnsping 也是正常的  但用plsql连接的时候总是报错 ora-12514 tns 监听程序无法识别连接描述符中请求的服务,因为连接本地数据库时没有问题的 所以监听程序应该没问题,接下来就查看tnsnames.ora 发现还是这里出了问题,其实报错报的已经说的很明确了 无法识别连接描述符中请求的服务 说明SID 和 服务名 是不一样的 我把 SE

nginx源代码分析--监听套接字的创建 套接字的监听 HTTP请求创建连接

作为一个webserver,那么肯定是有监听套接字的,这个监听套接字是用于接收HTTP请求的,这个监听套接字的创建是依据配置文件的内容来创建的,在nginx.conf文件里有多少个地址就须要创建多少个监听套接字.这里不说各个结构体的构造 仅仅说大体情况! 1).首先在main函数中调用了ngx_init_cycle()函数,在这个函数的最后调用了ngx_open_listening_sockets函数,这个函数负责将创建的监听套接字进行套接字选项的设置(比方非堵塞.接受发送的缓冲区.绑定.监听处

oracle11G 已开启监听,但远程连接依旧无监听解决过程

1.连接数据库显示无监听程序,首先查看服务器的oracle监听服务是否开启,服务名称:OracleOraDb11g_home1TNSListener(具体环境中可能不完全一样,但是认准TNSListener是没错的) 2.本地使用127.0.0.1可以连接,但使用本机IP则显示无监听,使用其他机器连接也是无监听,先排查一下防火墙问题 3.排查防火墙后依旧没有解决,那么问题根源所在:oracle的listener.ora文件 解决办法: listener.ora文件路径:F:\app\Admini

windows 下 PostgreSQL 监听配置及远程连接

PostgreSQL服务端运行在windows上,IP为:192.168.240.128 配置方法: 1.  修改服务端文件 你的安装目录/postgresql/data/postgresql.conf文件,将 #listen_address='localhost'改成listen_address='*'.有的默认就是,看版本. 2. 修改  /你的安装目录/postgresql/data/gp_hba.conf文件 在其中增加客户端的ip,如下,注意最后一行: # IPv4 localconn

PostgreSQL服务端监听设置及client连接方法

背景介绍: PostgreSQL服务端执行在RedHat Linux上,IP为:192.168.230.128 client安装在Windows XP上, IP为:192.168.230.1 配置方法: 1.  改动服务端/opt/postgresql/data/postgresql.conf文件,将 #listen_address='localhost'改成 listen_address='*' 2. 改动/opt/postgresql/data/gp_hba.conf文件 在当中添加clie

Linux/UNIX套接字连接

套接字连接 套接字是一种通信机子.凭借这样的机制.客户/server系统的开发工作既能够在本地单机上进行.也能够夸网络进行. 套接字的创建和使用与管道是有差别的.由于套接字明白地将客户和server区分开来. 套接字连接: 首先,server应用程序用系统调用socket来创建一个套接字,它是系统分配给该server进程的类似文件描写叙述符的资源,它不能与其它进程共享. 接下来.server进程会给套接字起个名字.本地套接字的名字是Linux文件系统中的文件名称,对于网络套接字它的名字是与客户连

为什么有监听socket和连接socket,为什么产生两个socket

为什么有监听socket和连接socket,为什么产生两个socket 先看一半的socket建立连接的双方的过程: 客户端: socket()---->创建出 active_socket_fd (client_socket_fd) bind()--->把active_socket_fd与ip,port绑定起来 connect()--->client_socket_fd 主动请求服务端的 listen_socket_fd read()/write()---->读/写 socket