up在python中是什么意思

本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类:

  • 消息传递(管道、FIFO、消息队列)

  • 同步(互斥量、条件变量、读写锁、文件和写记录锁、信号量)

  • 共享内存(匿名的和具名的)

但这些都不是本文的主题!我们要讨论的是网络中进程之间如何通信?首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行不通的。其实TCP/IP协议族已经帮我们解决了这个问题,网络层的“ip地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。这样利用三元组(ip地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。

使用TCP/IP协议的应用程序通常采用应用编程接口:UNIX  BSD的套接字(socket)和UNIX System V的TLI(已经被淘汰),来实现网络进程之间的通信。就目前而言,几乎所有的应用程序都是采用socket,而现在又是网络时代,网络中进程通信是无处不在,这就是我为什么说“一切皆socket”。


网络编程对所有开发语言都是一样的,Python也不例外。用Python进行网络编程,就是在Python程序本身这个进程内,连接别的服务器进程的通信端口进行通信。

    当您编写socket应用程序的时候,您可以在使用TCP还是使用UDP之间做出选择。它们都有各自的优点和缺点。
    TCP是流协议,而UDP是数据报协议。换句话说,TCP在客户机和服务器之间建立持续的开放连接,在该连接的生命期内,字节可以通过该连接写出(并且保证顺序正确)。然而,通过 TCP 写出的字节没有内置的结构,所以需要高层协议在被传输的字节流内部分隔数据记录和字段。
另一方面,UDP不需要在客户机和服务器之间建立连接,它只是在地址之间传输报文。UDP的一个很好特性在于它的包是自分隔的(self-delimiting),也就是一个数据报都准确地指出它的开始和结束位置。然而,UDP的一个可能的缺点在于,它不保证包将会按顺序到达,甚至根本就不保证。当然,建立在UDP之上的高层协议可能会提供握手和确认功能。
对于理解TCP和UDP之间的区别来说,一个有用的类比就是电话呼叫和邮寄信件之间的区别。在呼叫者用铃声通知接收者,并且接收者拿起听筒之前,电话呼叫不是活动的。只要没有一方挂断,该电话信道就保持活动,但是在通话期间,他们可以自由地想说多少就说多少。来自任何一方的谈话都按临时的顺序发生。另一方面,当你发一封信的时候,邮局在投递时既不对接收方是否存在作任何保证,也不对信件投递将花多长时间做出有力保证。接收方可能按与信件的发送顺序不同的顺序接收不同的信件,并且发送方也可能在他们发送信件是交替地接收邮件。与(理想的)邮政服务不同,无法送达的信件总是被送到死信办公室处理,而不再返回给发送。

除了TCP和UDP协议以外,通信一方(客户机或者服务器)还需要知道的关于与之通信的对方机器的两件事情:IP地址或者端口。IP地址是一个32位的数据值,为了人们好记,一般用圆点分开的4组数字的形式来表示,比如:.cn', 80))

创建Socket时,AF_INET指定使用IPv4协议,如果要用更先进的IPv6,就指定为AF_INET6SOCK_STREAM指定使用面向流的TCP协议,这样,一个Socket对象就创建成功,但是还没有建立连接。

客户端要主动发起TCP连接,必须知道服务器的IP地址和端口号。新浪网站的IP地址可以用域名.cn自动转换到IP地址,但是怎么知道新浪服务器的端口号呢?

答案是作为服务器,提供什么样的服务,端口号就必须固定下来。由于我们想要访问网页,因此新浪提供网页服务的服务器必须把端口号固定在80端口,因为80端口是Web服务的标准端口。其他服务都有对应的标准端口号,例如SMTP服务是25端口,FTP服务是21端口,等等。端口号小于1024的是Internet标准服务的端口,端口号大于1024的,可以任意使用。

因此,我们连接新浪服务器的代码如下:

注意参数是一个tuple,包含地址和端口号。

建立TCP连接后,我们就可以向新浪服务器发送请求,要求返回首页的内容:

TCP连接创建的是双向通道,双方都可以同时给对方发数据。但是谁先发谁后发,怎么协调,要根据具体的协议来决定。例如,HTTP协议规定客户端必须先发请求给服务器,服务器收到后才发数据给客户端。

发送的文本格式必须符合HTTP标准,如果格式没问题,接下来就可以接收新浪服务器返回的数据了:

接收数据时,调用recv(max)方法,一次最多接收指定的字节数,因此,在一个while循环中反复接收,直到recv()返回空数据,表示接收完毕,退出循环。

当我们接收完数据后,调用close()方法关闭Socket,这样,一次完整的网络通信就结束了:

接收到的数据包括HTTP头和网页本身,我们只需要把HTTP头和网页分离一下,把HTTP头打印出来,网页内容保存到文件:

# 把接收的数据写入文件:

现在,只需要在浏览器中打开这个sina.html文件,就可以看到新浪的首页了。

和客户端编程相比,服务器编程就要复杂一些。

服务器进程首先要绑定一个端口并监听来自其他客户端的连接。如果某个客户端连接过来了,服务器就与该客户端建立Socket连接,随后的通信就靠这个Socket连接了。

所以,服务器会打开固定端口(比如80)监听,每来一个客户端连接,就创建该Socket连接。由于服务器会有大量来自客户端的连接,所以,服务器要能够区分一个Socket连接是和哪个客户端绑定的。一个Socket依赖4项:服务器地址、服务器端口、客户端地址、客户端端口来唯一确定一个Socket。

但是服务器还需要同时响应多个客户端的请求,所以,每个连接都需要一个新的进程或者新的线程来处理,否则,服务器一次就只能服务一个客户端了。

我们来编写一个简单的服务器程序,它接收客户端连接,把客户端发过来的字符串加上Hello再发回去。

首先,创建一个基于IPv4和TCP协议的Socket:

然后,我们要绑定监听的地址和端口。服务器可能有多块网卡,可以绑定到某一块网卡的IP地址上,也可以用0.0.0.0绑定到所有的网络地址,还可以用127.0.0.1绑定到本机地址。127.0.0.1是一个特殊的IP地址,表示本机地址,如果绑定到这个地址,客户端必须同时在本机运行才能连接,也就是说,外部的计算机无法连接进来。

端口号需要预先指定。因为我们写的这个服务不是标准服务,所以用9999这个端口号。请注意,小于1024的端口号必须要有管理员权限才能绑定:

紧接着,调用listen()方法开始监听端口,传入的参数指定等待连接的最大数量:

接下来,服务器程序通过一个永久循环来接受来自客户端的连接,accept()会等待并返回一个客户端的连接:

# 创建新线程来处理TCP连接:

每个连接都必须创建新线程(或进程)来处理,否则,单线程在处理连接的过程中,无法接受其他客户端的连接:

连接建立后,服务器首先发一条欢迎消息,然后等待客户端数据,并加上Hello再发送给客户端。如果客户端发送了exit字符串,就直接关闭连接。

要测试这个服务器程序,我们还需要编写一个客户端程序:

我们需要打开两个命令行窗口,一个运行服务器程序,另一个运行客户端程序,就可以看到效果了:

TCP是建立可靠连接,并且通信双方都可以以流的形式发送数据。相对TCP,UDP则是面向无连接的协议。

使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。

虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。

我们来看看如何通过UDP协议传输数据。和TCP类似,使用UDP的通信双方也分为客户端和服务器。服务器首先需要绑定端口:

创建Socket时,SOCK_DGRAM指定了这个Socket的类型是UDP。绑定端口和TCP一样,但是不需要调用listen()方法,而是直接接收来自任何客户端的数据:

recvfrom()方法返回数据和客户端的地址与端口,这样,服务器收到数据后,直接调用sendto()就可以把数据用UDP发给客户端。

注意这里省掉了多线程,因为这个例子很简单。

客户端使用UDP时,首先仍然创建基于UDP的Socket,然后,不需要调用connect(),直接通过sendto()给服务器发数据:

从服务器接收数据仍然调用recv()方法。

UDP的使用与TCP类似,但是不需要建立连接。此外,服务器绑定UDP端口和TCP端口互不冲突,也就是说,UDP的9999端口与TCP的9999端口可以各自绑定。

Python 提供了两个级别访问的网络服务。:

  • 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法。
  • 高级别的网络服务模块 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发。
开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。
被动接受TCP客户端连接,(阻塞式)等待连接的到来
connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。
发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。
完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。
返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
返回套接字自己的地址。通常是一个元组(ipaddr,port)
设置给定套接字选项的值。
设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect())
返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。
返回套接字的文件描述符。
如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。
创建一个与该套接字相关连的文件
# 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。 # 被动接受TCP客户端连接,(阻塞式)等待连接的到来 # connect()函数的扩展版本,出错时返回出错码,而不是抛出异常 # 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。 # 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。 # 完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。 # 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。 # 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。 # 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。 # 返回套接字自己的地址。通常是一个元组(ipaddr,port) # 设置给定套接字选项的值。 # 返回套接字选项的值。 # 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect()) # 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。 # 返回套接字的文件描述符。 # 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。 # 创建一个与该套接字相关连的文件

  socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。
  socket.SOCK_RDM 是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。

  0  (默认)与特定的地址家族相关的协议,如果是 0 ,则系统就会根据地址格式和套接类别,自动选择一个合适的协议

  s.bind(address) 将套接字绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组(host,port)的形式表示地址。

  开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。

      backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5
      这个值不能无限大,因为要在内核中维护连接队列

  是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错。

  接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。

  接收TCP 客户的连接(阻塞式)等待连接的到来

  同上,只不过会有返回值,连接成功时返回 0 ,连接失败时候返回编码,例如:10061

  接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。flag提供有关消息的其他信息,通常可以忽略。

  与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。

  将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。

  将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。

  将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。该函数主要用于UDP协议。

  设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如 client 连接最多等待5s )

  返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。

  返回套接字自己的地址。通常是一个元组(ipaddr,port)

  套接字的文件描述符

 实例:智能机器人

I/O多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。

select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组,当select()返回后,该数组中就绪的文件描述符便会被内核修改标志位,使得进程可以获得这些文件描述符从而进行后续的读写操作。 select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点,事实上从现在看来,这也是它所剩不多的优点之一。 select的一个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,不过可以通过修改宏定义甚至重新编译内核的方式提升这一限制。 另外,select()所维护的存储大量文件描述符的数据结构,随着文件描述符数量的增大,其复制的开销也线性增长。同时,由于网络响应时间的延迟使得大量TCP连接处于非活跃状态,但调用select()会对所有socket进行一次线性扫描,所以这也浪费了一定的开销。 poll和select同样存在一个缺点就是,包含大量文件描述符的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符是否就绪,它的开销随着文件描述符数量的增加而线性增大。 另外,select()和poll()将就绪的文件描述符告诉进程后,如果进程没有对其进行IO操作,那么下次调用select()和poll()的时候将再次报告这些文件描述符,所以它们一般不会丢失就绪的消息,这种方式称为水平触发(Level Triggered)。 直到Linux2.6才出现了由内核直接支持的实现方法,那就是epoll,它几乎具备了之前所说的一切优点,被公认为Linux2.6下性能最好的多路I/O就绪通知方法。 epoll可以同时支持水平触发和边缘触发(Edge Triggered,只告诉进程哪些文件描述符刚刚变为就绪状态,它只说一遍,如果我们没有采取行动,那么它将不会再次告知,这种方式称为边缘触发),理论上边缘触发的性能要更高一些,但是代码实现相当复杂。 epoll同样只告知那些就绪的文件描述符,而且当我们调用epoll_wait()获得就绪文件描述符时,返回的不是实际的描述符,而是一个代表就绪描述符数量的值,你只需要去epoll指定的一个数组中依次取得相应数量的文件描述符即可,这里也使用了内存映射(mmap)技术,这样便彻底省掉了这些文件描述符在系统调用时复制的开销。 另一个本质的改进在于epoll采用基于事件的就绪通知方式。在select/poll中,进程只有在调用一定的方法后,内核才对所有监视的文件描述符进行扫描,而epoll事先通过epoll_ctl()来注册一个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,当进程调用epoll_wait()时便得到通知。

注意:网络操作、文件操作、终端操作等均属于IO操作,对于windows只支持Socket操作,其他系统支持其他IO操作,但是无法检测 普通文件操作 自动上次读取是否已经变化。

参数: 可接受四个参数(前三个必须) select方法用来监视文件句柄,如果句柄发生变化,则获取该句柄。 1、当 参数1 序列中的句柄发生可读时(accetp和read),则获取发生变化的句柄并添加到 返回值1 序列中 2、当 参数2 序列中含有句柄时,则将该序列中所有的句柄添加到 返回值2 序列中 3、当 参数3 序列中的句柄发生错误时,则将该发生错误的句柄添加到 返回值3 序列中 4、当 超时时间 未设置,则select会一直阻塞,直到监听的句柄发生变化 当 超时时间 = 1时,那么如果监听的句柄均无任何变化,则select会阻塞 1 秒,之后返回三个空列表,如果监听的句柄有变化,则直接执行。
利用select监听终端操作实例

 利用select实现伪同时处理多个socket客户端请求:服务端

# 当客户端第一次连接服务端时 # 当客户端连接上服务端之后,再次发送数据时 # 当正常接收客户端发送的数据时 # 当客户端关闭程序时 利用select实现伪同时处理多个Socket客户端请求:服务端

 利用select实现伪同时处理多个socket客户端请求:客户端

利用select实现伪同时处理多个Socket客户端请求:客户端

 此处的Socket服务端相比与原生的Socket,他支持当某一个请求不再发送数据时,服务器端不会等待而是可以去处理其他请求的数据。但是,如果每个请求的耗时比较长时,select版本的服务器端也无法完成同时操作。

服务器的实现 采用select的方式 #创建套接字并设置该套接字为非阻塞模式 #将该socket变成服务模式 #backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5 #这个值不能无限大,因为要在内核中维护连接队列 #初始化读取数据的监听列表,最开始时希望从server这个套接字上读取数据 #初始化写入数据的监听列表,最开始并没有客户端连接进来,所以列表为空 #调用select监听所有监听列表中的套接字,并将准备好的套接字加入到对应的列表中 #监控文件句柄有某一处发生了变化 可写 可读 异常属于Linux中的网络编程 #属于同步I/O操作,属于I/O复用模型的一种 如果server这个套接字可读,则说明有新链接到来 此时在server套接字上调用accept,生成一个与客户端通讯的套接字 并将与客户端通讯的套接字加入inputs列表,下一次可以通过select检查连接是否可读 然后在发往客户端的缓冲中加入一项,键名为:与客户端通讯的套接字,键值为空队列 select系统调用是用来让我们的程序监视多个文件句柄(file descrīptor)的状态变化的。程序会停在select这里等待, 直到被监视的文件句柄有某一个或多个发生了状态改变 若可读的套接字不是server套接字,有两种情况:一种是有数据到来,另一种是链接断开 如果有数据到来,先接收数据,然后将收到的数据填入往客户端的缓存区中的对应位置,最后 将于客户端通讯的套接字加入到写数据的监听列表: 如果套接字可读.但没有接收到数据,则说明客户端已经断开。这时需要关闭与客户端连接的套接字 在发送缓冲区中取出响应的数据,发往客户端。 如果没有数据需要写,则将套接字从发送队列中移除,select中不再监视

SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,从而实现并发处理多个客户端请求的Socket服务端。即:每个客户端请求连接到服务器时,Socket服务端都会在服务器是创建一个“线程”或者“进程” 专门负责处理当前客户端的所有请求。

ThreadingTCPServer实现的Soket服务器内部会为每个client创建一个 “线程”,该线程用来和客户端进行交互。

  • 类中必须定义一个名称为 handle 的方法
  • 当客户端连接到达服务器

Socket(翻译为套接字, 我觉得很挫),是操作系统内核中的一个数据结构,它是网络中的节点进行相互通信的门户。它是网络进程的ID。网络通信,归根到底还是进程间的通信(不同计算机上的进程间通信, 又称进程间通信, IP协议进行的主要是端到端通信)。在网络中,每一个节点(计算机或路由)都有一个网络地址,也就是IP地址。两个进程通信时,首先要确定各自所在的网络节点的网络地址。但是,网络地址只能确定进程所在的计算机,而一台计算机上很可能同时运行着多个进程,所以仅凭网络地址还不能确定到底是和网络中的哪一个进程进行通信,因此套接口中还需要包括其他的信息,也就是端口号(PORT)。在一台计算机中,一个端口号一次只能分配给一个进程,也就是说,在一台计算机中,端口号和进程之间是一一对应关系。
所以,使用端口号和网络地址的组合可以唯一的确定整个网络中的一个网络进程.

端口号的范围从0~65535,一类是由互联网指派名字和号码公司ICANN负责分配给一些常用的应用程序固定使用的“周知的端口”,其值一般为0~1023, 用户自定义端口号一般大于等于1024, 我比较喜欢用8888

每一个socket都用一个半相关描述{协议、本地地址、本地端口}来表示;一个完整的套接字则用一个相关描述{协议、本地地址、本地端口、远程地址、远程端口}来表示。socket也有一个类似于打开文件的函数调用,该函数返回一个整型的socket描述符,随后的连接建立、数据传输等操作都是通过socket来实现的。

# 3 服务器socket监听端口号请求,随时准备接收客户端发来的连接,这时候服务器的socket并没有被打开 # 5 客户端打开socket,根据服务器ip地址和端口号试图连接服务器socket # 6 服务器socket接收到客户端socket请求,被动打开,开始接收客户端请求,直到客户端返回连接信息。这时候socket进入阻塞状态, # 所谓阻塞即accept()方法一直等到客户端返回连接信息后才返回,开始接收下一个客户端连接请求 # 7 客户端连接成功,向服务器发送连接状态信息 # 8 服务器accept方法返回,连接成功 # 10 服务器读取信息(客户端读取信息) # 12 服务器端关闭

只能够用于单一的Unix系统进程间通信

原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。

流式套接字提供可靠的、面向连接的通信流;它使用TCP协议,从而保证了数据传输的正确性和顺序性

数据报套接字定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证是可靠、无差错的。它使用数据报协议UDP

  • 原始socket(SOCK_RAW) 用于新的网络协议实现的测试等

原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以, 其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。


使用给定的地址族、套接字类型、协议编号(默认为0)来创建套接字

返回值:成功则返回套接口描述符,失败返回-1。
返回值:成功则返回0,失败返回-1 post: 自定义主机号, 为整型

使服务器的这个端口和IP处于监听状态,等待网络中某一客户机的连接请求。如果客户端有连接请求,端口就会接受这个连接

backlog : 指定同时能处理的最大连接要求,通常为10或者5。最大值可设至128 返回值:成功则返回0,失败返回-1 backlog : 操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了

接受远程计算机的连接请求,建立起与客户机之间的通信连接。服务器处于监听状态时,如果某时刻获得客户机的连接请求,此时并不是立即处理这个请求,而是将这个请求放在等待队列中,当系统空闲时再处理客户机的连接请求。

addr : 为结构体指针变量,和bind的结构体是同种类型的,系统会把远程主机的信息(远程主机的地址和端口号信息)保存到这个指针所指的结构体中。 addrlen : 表示结构体的长度,为整型指针 返回值:成功则返回新的socket处理代码new_fd,失败返回-1 返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址

用来请求连接远程服务器

serv_addr : 为结构体指针变量,存储着远程服务器的IP与端口号信息 返回值:成功则返回0,失败返回-1

接收远端主机传来的数据

len : 表示缓冲区的长度 返回值:成功则返回实际接收到的字符数,可能会少于你所指定的接收长度。失败返回-1 flag : 提供有关消息的其他信息,通常可以忽略 返回值为数据以字符串形式

发送数据给指定的远端主机

msg : 一般为常量字符串 返回值:成功则返回实际传送出去的字符数,可能会少于你所指定的发送长度。失败返回-1 flag : 提供有关消息的其他信息,通常可以忽略 返回值是要发送的字节数量,该数量可能小于string的字节大小。 #完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。 返回值 : 成功返回None,失败则抛出异常。
返回值:若文件顺利关闭则返回0,发生错误时返回-1

简单的客户端服务器TCP连接

一个简单的回显服务器和客户端模型, 客户端发出的数据, 服务器会回显到客户端的终端上(只是一个简单的模型, 没考虑错误处理等问题)

 带错误处理的客户端服务器TCP连接

在进行网络编程时, 最好使用大量的错误处理, 能够尽量的发现错误, 也能够使代码显得更加严谨

发送UDP数据, 将数据发送到套接字

msg : 一般为常量字符串 to : 表示目地机的IP地址和端口号信息, 表示地址的结构体 返回值 : 返回实际发送的数据字节长度或在出现发送错误时返回-1。 flag : 提供有关消息的其他信息,通常可以忽略 返回值 : 发送的字节数。
msg : 一般为常量字符串 from :是一个struct sockaddr类型的变量,该变量保存连接机的IP地址及端口号 返回值 : 返回接收到的字节数或当出现错误时返回-1,并置相应的errno。 返回值 : (data,address)元组, 其中data是包含接收数据的字符串,address是发送数据的套接字地址 flag : 提供有关消息的其他信息,通常可以忽略

简单的客户端服务器UDP连接

#返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。 #返回套接字自己的地址。通常是一个元组(ipaddr,port) #设置给定套接字选项的值。 #返回套接字选项的值。 #设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect()) #返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。 #返回套接字的文件描述符。 #如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。 #创建一个与该套接字相关连的文件
 

这个警告的主要部分是took 1.723 seconds:警告说某个协同程序(或任务)已经冻结了事件循环1.7秒,这不是正常情况(如果您不明白原因,请阅读答案或更好的)。在

正如您所提到的,asyncio只在调试模式打开时跟踪这个问题。在

无论调试模式如何,都会收到此警告,这意味着在调用loop.close()时,仍有正在运行的任务。这又不是正常情况(阅读看看原因)。在


如果没有可复制的代码片段,很难说得更多。在

如果您将任务存储在WeakValueDictionary中,可能会出现问题,是的。在关闭事件循环之前,您应该所有任务(或等待它们完成)。在

我要回帖

更多关于 penup在python是什么意思 的文章

 

随机推荐