zoukankan      html  css  js  c++  java
  • python-kafka源码解析之socketpair

    socket基本操作包括:
    socket()函数创建socket文件描述符,唯一标识一个socket。
    bind()函数,将ip:port和socket绑定
    listen()函数来监听这个socket,假如客户端connect这个套接字,服务器端就回接收到这个连接请求。
    connect()函数用于和服务端建立连接
    accept()函数,服务端经过bind和listen,并且客户端connect后,服务端用accept接收这个建立连接的请求。
    read()、write()等函数,用于建立连接后的信息交互。
    详情参考:Linux Socket编程(不限Linux)

    python-kafak中vendor包下socketpair源码如下,返回在127.0.0.1本地连接的两端socket,ssock表示服务端socket,csock表示客户端socket。

     1 # pylint: skip-file
     2 # vendored from https://github.com/mhils/backports.socketpair
     3 from __future__ import absolute_import
     4 
     5 import sys
     6 import socket
     7 import errno
     8 
     9 _LOCALHOST    = '127.0.0.1'
    10 _LOCALHOST_V6 = '::1'
    11 
    12 #socketpair返回本地建立连接的两端socket
    13 if not hasattr(socket, "socketpair"):
    14     # Origin: https://gist.github.com/4325783, by Geert Jansen.  Public domain.
    15     def socketpair(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):
    16         if family == socket.AF_INET: #ipv4
    17             host = _LOCALHOST
    18         elif family == socket.AF_INET6: #ipv6
    19             host = _LOCALHOST_V6
    20         else:
    21             raise ValueError("Only AF_INET and AF_INET6 socket address families "
    22                              "are supported")
    23         if type != socket.SOCK_STREAM:
    24             raise ValueError("Only SOCK_STREAM socket type is supported")
    25         if proto != 0:
    26             raise ValueError("Only protocol zero is supported")
    27 
    28         # We create a connected TCP socket. Note the trick with
    29         # setblocking(False) that prevents us from having to create a thread.
    30         lsock = socket.socket(family, type, proto)
    31         try:
    32             lsock.bind((host, 0)) #端口0说明由系统动态创建监听端口
    33             lsock.listen(min(socket.SOMAXCONN, 128))#SOMAXCONN定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数,默认值为128,https://jaminzhang.github.io/linux/understand-Linux-backlog-and-somaxconn-kernel-arguments/
    34             # On IPv6, ignore flow_info and scope_id
    35             addr, port = lsock.getsockname()[:2]#返回这个socket的地址
    36             csock = socket.socket(family, type, proto)
    37             try:
    38                 csock.setblocking(False)#设置socket为非阻塞模式,非阻塞模式下recv没有收到数据或send数据没有立即发送出去,则会抛出异常,等价于s.settimeout(0.0)。
    39                 # 阻塞模式,会等待直到有数据或数据发送出去,等价于s.settimeout(None)
    40                 if sys.version_info >= (3, 0):
    41                     try:
    42                         csock.connect((addr, port))
    43                     except (BlockingIOError, InterruptedError):
    44                         pass
    45                 else:
    46                     try:
    47                         csock.connect((addr, port))##连接本地创建的lsock
    48                     except socket.error as e:
    49                         if e.errno != errno.WSAEWOULDBLOCK:
    50                             raise
    51                 csock.setblocking(True)#重新设置socket为阻塞模式
    52                 ssock, _ = lsock.accept()#服务端socket接收连接返回和特定客户端建立连接后的新socket ssock
    53             except Exception:
    54                 csock.close()
    55                 raise
    56         finally:
    57             lsock.close()#关闭监听套接字lsock
    58         return (ssock, csock)#返回本地互相连接的两端socket
    59 
    60     socket.socketpair = socketpair

       其中23行参数为(ip:port),端口0表示端口由操作系统自动选取监听端口;33行参数为backlog,表示服务端连接队列的大小。服务端分为两个队列,一个存放 SYN 的队列(半连接队列)、一个存放已经完成连接的队列(全连接队列)。backlog不能超过内核参数somaxconn,高并发情况下加大连接队列长度需调内核参数somaxconn

  • 相关阅读:
    随笔:我为什么要写博客?
    用纯C语言写的一个植物大战僵尸的外挂
    方法:如何获取操作系统所有分区(逻辑驱动器)
    Srping syntactically incorrect.错误记录
    重建项目报错
    easyui datagrid 跨页选择
    CentOS 6编译安装ipvsadm和keepalived
    CentOS 6下ActiveMQ 5.5安装及使用MySQL
    extjs 4中TreePanel和GridPanel使用
    Linux安装性能问题
  • 原文地址:https://www.cnblogs.com/killianxu/p/11075192.html
Copyright © 2011-2022 走看看