一篇文章带你理解套接字Socket的各个接口


大家好,我是Song同学,时间过得很快,我觉得人生还是得有自己的追求,我也不希望自己的大学四年和今后的生活是在玩乐中度过,希望自己每天都有收获,在CSDN上记录下自己的学习过程,主要是更新算法、QT、C++以及Linux相关的内容,希望自己能够早日成为C/C++ 高级程序员,也希望大家能够通过我的分享有所收获,共同进步!


前言

从Linux内核的角度来看,一个套接字就是通信的一个端点,从Linux程序来说,套接字就是一个有相应文件描述符的打开文件,在Linux中一切皆文件,网络也可以看作是文件,通过建立描述符来进行网络通信。
要记住客户端和服务器是进程,而不是我们常提到的主机和机器

Socket函数

客户端和服务器端使用socket函数来创建一个套接字描述符

#include <sys/types.h>
#include <sys/socket.h>

int socket(int domain,int type,int protocol);//成功返回描述符,出错则返回-1

client_fd=socket(AF_INET,SOCK_STREAM,0);

  • AF_INET表明我们正在使用32位IP地址(ipv4)
  • SOCK_STREAM表示这个套接字是连接的一个端点

以后介绍利用getaddrinfo函数来自动生成这些参数,更加方便,现在写最基础的


connect函数

客户端通过调用connect函数来建立和服务器的1连接

#include <sys/socket.h>

int connect(int clientfd,const struct sockaddr *addr,socklen_t addrlen);//成功返回0,出错返回-1

connect函数试图与套接字地址为addr的服务器建立-一个因特网连接,其中addrlen是sizeof (sockaddr_ in)。 connect 函数会阻塞,一直 到连接成功建立或是发生错误。如果成功,clientfd描述符现在就准备好可以读写了,并且得到的连接是由套接字对
(x:y, addr.sin _addr: addr.sin. port)
刻画的,其中x表示客户端的IP地址,而y表示临时端口,它唯一地确定了客户端主机上的客户端进程。 对于socket, 最好的方法是用getaddrinfo 来为connect 提供参数


以下的接口都是为服务器利用,用来和客户端建立连接

bind函数

#include <sys/socket.h>

int bind(int serverfd, const struct sockaddr *addr,socklen_t addrlen);

bind函数是把地址和服务器的套接字描述符进行绑定,让客户端可以通过地址找到相对应得服务器,地址包括IP地址还有端口号,同样的还是可以用getaddrinfo来为bind提供参数,但还是先不写😂


listen函数

客户端是发起连接请求的主动实体。服务器是等待来自客户端的连接请求的被动实体。默认情况下,内核会认为socket函数创建的描述符对应于主动套接字, 它存在于一个连接的客户端。服务器调用listen函数告诉内核,描述符是被服务器而不是客户端使用的。

#include <sys/socket.h>

int listen(int sockfd,int backlog);//成功返回0,出错返回-1

listen函数将sockfd从一个主动套接字转化为一个监听套接字,该套接字可以接受来自客户端的连接请求。backlog参数暗示了内核在开始拒绝连接请求之前,队列中要排队的未完成的连接请求的数量(这就涉及到几次握手了,到后面再来说吧,现在就先理解为:如果有多个客户端在前一个已连接的客户端还没断开连接的情况下对服务器端进行连接,那么这些后面加入的客户端需要加入一个队列进行排队),如果排队的客户端个数大已经等于backlog那么后面再继续加进来,则会被拒绝连接。backlog参数的确切含义要求对TCP/IP协议的理解,这就后面再讨论喽,通常我们会把它设置为一个较大的值,比如1024


accept函数

服务器通过调用accept函数来等待来自客户端的连接请求

#include <sys/socket.h>

int accept(int listenfd, struct sockaddr *addr, int *addrlen);//成功返回对应客户端非负的连接描述符,出错返回-1

通过accept函数返回一个已连接描述符,这个描述符可被用来利用Unix I/O函数和客户端通信,简单理解就是用一个client_sock来解accept函数的返回值,然后通过这个client_sock和客户端进行通信。

监听描述符和已连接描述符之间的区别使很多人感到迷惑。监听描述符是作为客户端连接请求的一个端点。它通常被创建一次,并存在于服务器的整个生命周期。已连接描述符是客户端和服务器之间已经建立起来了的连接的一个端点。 服务器每次接受连接请求时都会创建一一次, 它只存在于服务器为一个客户端服务的过程中。
下图是描绘了监听描述符和已连接描述符的角色:
在这里插入图片描述


为什么要有监听描述符和已连接描述符,他们间的区别是什么

你可能很想知道为什么套接字接口要区别监听描述符和已连接描述符。乍一看,这像是不必要的复杂化。然而,区分这两者被证明是很有用的,因为它使得我们可以建立并发服务器,它能够同时处理许多客户端连接。例如,每次一个连接请求到达监听描述符时,我们可以派生一个新的进程,它通过已连接描述符与客户端通信。

感觉《深入理解计算机系统》这本书还是很好的,我感觉它书中的表示已经很清晰了,我在这篇文章中还是有挺多的话都是来自这本书的,从汇编讲到网络,是循序渐进的,由浅到深,思维也不会太跳跃,真心推荐大家去瞧瞧(๑•̀ㅂ•́)و✧

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值