python入门第二十六天--网络通信
Posted 独孤_败天
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python入门第二十六天--网络通信相关的知识,希望对你有一定的参考价值。
网络编程
自从互联网诞生以来,现在基本上所有的程序都是网络程序,很少有单机版的程序了。
计算机网络就是把各个计算机连接到一起,让网络中的计算机可以互相通信。网络编程就是如何在程序中实现两台计算机的通信。
举个例子,当你使用浏览器访问新浪网时,你的计算机就和新浪的某台服务器通过互联网连接起来了,然后,新浪的服务器把网页内容作为数据通过互联网传输到你的电脑上。
由于你的电脑上可能不止浏览器,还有QQ、Skype、Dropbox、邮件客户端等,不同的程序连接的别的计算机也会不同,所以,更确切地说,网络通信是两台计算机上的两个进程之间的通信。比如,浏览器进程和新浪服务器上的某个Web服务进程在通信,而QQ进程是和腾讯的某个服务器上的某个进程在通信。
网络编程对所有开发语言都是一样的,Python也不例外。用Python进行网络编程,就是在Python程序本身这个进程内,连接别的服务器进程的通信端口进行通信。
本章我们将详细介绍Python网络编程的概念和最主要的两种网络类型的编程。
TCP/IP简介
虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多。
计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM、Apple和Microsoft都有各自的网络协议,互不兼容,这就好比一群人有的说英语,有的说中文,有的说德语,说同一种语言的人可以交流,不同的语言之间就不行了。
为了把全世界的所有不同类型的计算机都连接起来,就必须规定一套全球通用的协议,为了实现互联网这个目标,互联网协议簇(Internet Protocol Suite)就是通用协议标准。Internet是由inter和net两个单词组合起来的,原意就是连接“网络”的网络,有了Internet,任何私有网络,只要支持这个协议,就可以联入互联网。
因为互联网协议包含了上百种协议标准,但是最重要的两个协议是TCP和IP协议,所以,大家把互联网的协议简称TCP/IP协议。
通信的时候,双方必须知道对方的标识,好比发邮件必须知道对方的邮件地址。互联网上每个计算机的唯一标识就是IP地址,类似123.123.123.123
。如果一台计算机同时接入到两个或更多的网络,比如路由器,它就会有两个或多个IP地址,所以,IP地址对应的实际上是计算机的网络接口,通常是网卡。
IP协议负责把数据从一台计算机通过网络发送到另一台计算机。数据被分割成一小块一小块,然后通过IP包发送出去。由于互联网链路复杂,两台计算机之间经常有多条线路,因此,路由器就负责决定如何把一个IP包转发出去。IP包的特点是按块发送,途径多个路由,但不保证能到达,也不保证顺序到达。
IP地址实际上是一个32位整数(称为IPv4),以字符串表示的IP地址如192.168.0.1
实际上是把32位整数按8位分组后的数字表示,目的是便于阅读。
IPv6地址实际上是一个128位整数,它是目前使用的IPv4的升级版,以字符串表示类似于2001:0db8:85a3:0042:1000:8a2e:0370:7334
。
TCP协议则是建立在IP协议之上的。TCP协议负责在两台计算机之间建立可靠连接,保证数据包按顺序到达。TCP协议会通过握手建立连接,然后,对每个IP包编号,确保对方按顺序收到,如果包丢掉了,就自动重发。
许多常用的更高级的协议都是建立在TCP协议基础上的,比如用于浏览器的HTTP协议、发送邮件的SMTP协议等。
一个TCP报文除了包含要传输的数据外,还包含源IP地址和目标IP地址,源端口和目标端口。
端口有什么作用?在两台计算机通信时,只发IP地址是不够的,因为同一台计算机上跑着多个网络程序。一个TCP报文来了之后,到底是交给浏览器还是QQ,就需要端口号来区分。每个网络程序都向操作系统申请唯一的端口号,这样,两个进程在两台计算机之间建立网络连接就需要各自的IP地址和各自的端口号。
一个进程也可能同时与多个计算机建立链接,因此它会申请很多端口。
了解了TCP/IP协议的基本概念,IP地址和端口的概念,我们就可以开始进行网络编程了。
OSI七层模型
OSI模型是开放系统互连参考模型,为开放式的互连信息提供一种功能的框架。举个栗子,你通过计算机向其他人传递某一个信息的时候,要保证信息正确准确的传递到他的计算机上,就要遵守一定的协议。否则,他的计算机可能就不能识别你的信息。这个协议是人为建立的,在1979年国际标准化组织建立了一个分委会来专门研究一种用于开放系统的体系结构,用来定义连接异种计算机的标准主体结构。
同层之间的通信规则和约定被称之为协议。这个协议贯彻了计算的硬件和软件。
第一层:物理层
为设备之间的信息传输提供可靠环境,那么这个环境是什么呢?
就是如:同轴电缆,插头,接收器,水晶头,网线等。可以在通信的两个数据终端的设备之间连接起来形成一条通路。
再说下这个协议中的某一项规定:比如eiars-232-c及rs-449就可以兼容于100序列线上。
第二层:数据链路层
提供数据的传送服务。这里涉及到一个信息就是帧,它是数据传输的单元,不同的协议帧的长短也不同。它还有差错恢复,流量控制的功能(这个指的是硬件)
ISO1745--1975 、ISO7776 、ISO3309--1984 就是这一层的三种不同协议,而每一个协议帧的长短也是不同的。
我们常见的链路层产品就是网卡,网桥等。
第三层:网络层
它的作用是路由的选择,网络的激活和终止。它还有的一个重要功能就是在一条数据链路上复用多条网络连接,大多采用的是分时复用的技术。
我们常见的是路由器、网关等
第四层:传输层
它是两台计算机经过网络进行数据通信时最基础的端到端的一个层次。它的服务满足了传送质量,传达速度,传送费用的不同需要。它还具有差错恢复,流量控制的功能(这个指的是软件)
很多时候我们会发现QQ聊天的速度很快,但是我们上网速度就很慢,这就是因为QQ使用UDP协议,没有纠错功能,而网络的传输使用的是TCP协议,它的纠错功能就会导致传输速度变慢。
第五层:会话层
它的服务可使应用建立和维持会话。再举个栗子:就像两个人打电话,一个人说,对方听到后回应他,这就是会话层在发挥作用,它能够使信息传递时保持同步,并按次序进行。
第六层:表示层
它包括数据的表示形式,文字,图形,图片等都有各自的格式,就像图片的格式有JPG,GIF等。
还有就是数据含义,就是数据的符号
这一层的作用就是为异种机通信提供一种公共语言,以便相互操作。例如,IBM主机使用EBCDIC编码,而大部分的PC机使用的是ASCII码。这就要表示层来完成这一转换。
第七层:应用层
实现应用进程之间的信息交换。同时还有一系列的业务处理所需要的服务功能。像文件的传送,访问和管理,打印服务都是属于应用层。
七层模型是很抽象的一个概念。一般情况下,物理层,数据链路层,网络层对应的是一个设备,这个设备在某一层就有某种功能,而传输层,会话层,表示层对应的是协议,而应用层就是使用什么样的软件。
OSI七层网络模型 |
TCP/IP四层概念模型 |
对应网络协议 |
应用层(Application) |
应用层 |
HTTP、TFTP, FTP, NFS, WAIS、SMTP |
表示层(Presentation) |
Telnet, Rlogin, SNMP, Gopher |
|
会话层(Session) |
SMTP, DNS |
|
传输层(Transport) |
传输层 |
TCP, UDP |
网络层(Network) |
网络层 |
IP, ICMP, ARP, RARP, AKP, UUCP |
数据链路层(Data Link) |
数据链路层 |
FDDI, Ethernet, Arpanet, PDN, SLIP, PPP |
物理层(Physical) |
IEEE 802.1A, IEEE 802.2到IEEE 802.11 |
网络编程三大要素。
(1)IP地址:网络中每一台计算机的唯一标识,通过IP地址找到指定的计算机。
(2)端口:用于标识进程的逻辑地址,通过端口找到指定进程。
(3)协议:定义通信规则,符合协议则可以通信,不符合不能通信。
用生活中的例子说明:假如我要和小明说话,首先我要到小明的住址找到小明(相当于通过IP找到指定计算机);之后我要和小明说话,小明用耳朵听我说(相当于用端口接收);而我们对话不能使用鸟语,需要作出规定彼此都要使用都能听懂的普通话(这就是协议的作用了)。
详解IP地址
IP地址:是网络中计算机的唯一标识,通过IP地址可以找到指定计算机。
假如有一个192.168.26.254 的IP地址,它在网络中其实是这样用四个字节表示的:11000000 10101000 00011010 11111110,使用0、1表示,而且中间没有点,因为这种表示形式不容易记(还要计算二进制数),所以使用192.168.26.254的形式,这种形式叫做“点分十进制”。也因为一个字节最大值为255,所以组成点分十进制的四个数字每个都不能超过255。
IP地址分成五类:
A类 1.0.0.1---127.255.255.254(10.X.X.X是私有地址、127.X.X.X是保留地址)
B类 128.0.0.1---191.255.255.254(172.16.0.0---172.31.255.255是私有地址,169.254.X.X是保留地址)
C类 192.0.0.1---223.255.255.254,(192.168.X.X也是私有地址,还记得我们大学的网关就是192.168.26.254)
D类 224.0.0.1---239.255.255.254(保留地址)
E类 240.0.0.1---247.255.255.254(保留地址)
附:私有地址,是在互联网上不使用,被用在局域网络中的地址。
IP地址的组成:IP地址由网络号段(不可变)和主机地址(可变)组成(表示形式:IP地址 = 网络号码+主机地址)。
A类IP地址:第一段号码为网络号码,剩下的三段是本地计算机的号码,所以A类共有 256*256*256=16777216,一千多万个IP地址,貌似中国电信有A类地址。
B类IP地址:前二段号码为网络号码,剩下的二段是本地计算机的号码,共65536个IP,大型学校可以用B类。
C类IP地址:前三段号码为网络号码,剩下的一段号码为本地计算机的号码,共256个IP,一般公司可以使用。
查看IP:通常电脑联网有问题了,经常使用ping方法,简单来说,ping 只是一个对联网环境的检测,并不能解决问题,记得当初刚开始学到的时候,还以为ping一下就能够把断掉的网连上(好幼稚。。)。
具体方法:
查看本机IP:ipconfig。
查看本机网络环境:ping 127.0.0.1(本机回环地址),连不上网的时候可以ping一下本机回环地址,看是否是自己电脑的问题。
查看网络是否有问题: ping+IP地址,如果自己电脑没问题,就可以ping一下其它IP了,学校电脑连不上网的时候经常ping学校网关,其实ping百度(ping www.baidu.com),ping搜狐都是可以的。
端口:
物理端口:网卡口。
逻辑端口:用于标识进程的逻辑地址,不同进程使用的端口是不同的,计算机通过端口找到指定进程,有效端口为0~6+5535,其中1~1024是系统使用的端口或保留端口。
TCP协议中的三次握手和四次挥手(图解)
建立TCP需要三次握手才能建立,而断开连接则需要四次握手。整个过程如下图所示:
先来看看如何建立连接的。
首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源。Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP连接就建立了。
那如何断开连接呢?简单的过程如下:
【注意】中断连接端可以是Client端,也可以是Server端。
假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!
整个过程Client端所经历的状态如下:
而Server端所经历的过程如下:转载请注明:blog.csdn.net/whuslei
【注意】 在TIME_WAIT状态中,如果TCP client端最后一次发送的ACK丢失了,它将重新发送。TIME_WAIT状态中所需要的时间是依赖于实现方法的。典型的值为30秒、1分钟和2分钟。等待之后连接正式关闭,并且所有的资源(包括端口号)都被释放。
【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。
为什么要四次挥手
TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工模式,这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;但是,这个时候主机1还是可以接受来自主机2的数据;当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。
几个基本概念
SYN:
Synchronous 建立联机
ACK:
Acknowledgement 确认
PSH:
Push 传送
FIN:
Finish 结束
RST:
Reset 重置
URG:
Urgent 紧急
CLOSED:
表示初始状态。
LISTEN:
表示服务器端的某个SOCKET处于监听状态,可以接受连接了。
SYN_RCVD:
这个状态表示接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat是很难看到这种状态的,除非特意写了一个客户端测试程序,故意将三次TCP握手过程中最后一个ACK报文不予发送。因此这种状态时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。
SYN_SENT:
这个状态与SYN_RCVD遥相呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。
ESTABLISHED:
表示连接已经建立。
SOCKET 编程
要想理解socket,就要先来理解TCP,UDP协议
TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,定义了主机如何连入因特网及数据如何再它们之间传输的标准,
从字面意思来看TCP/IP是TCP和IP协议的合称,但实际上TCP/IP协议是指因特网整个TCP/IP协议族。不同于ISO模型的七个分层,TCP/IP协议参考模型把所有的TCP/IP系列协议归类到四个抽象层中
应用层:TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 等等
传输层:TCP,UDP
网络层:IP,ICMP,OSPF,EIGRP,IGMP
数据链路层:SLIP,CSLIP,PPP,MTU
每一抽象层建立在低一层提供的服务上,并且为高一层提供服务,看起来大概是这样子的
我们可以利用ip地址+协议+端口号唯一标示网络中的一个进程。能够唯一标示网络中的进程后,它们就可以利用socket进行通信了,我们经常把socket翻译为套接字,socket是在应用层和传输层(TCP/IP协议族通信)之间的一个抽象层,是一组接口,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。
应用程序两端通过“套接字”向网络发出请求或者应答网络请求。可以把socket理解为通信的把手(hand)
socket起源于UNIX,在Unix一切皆文件哲学的思想下,socket是一种"打开—读/写—关闭"模式的实现,服务器和客户端各自维护一个"文件",在建立连接打开后,可以向自己文件写入内容供对方读取或者读取对方内容,通讯结束时关闭文件。socket的英文原义是“插槽”或“插座”,就像我们家里座机一样,如果没有网线的那个插口,电话是无法通信的。Socket是实现TCP,UDP协议的接口,便于使用TCP,UDP。
socket通信流程
Socket是网络编程的一个抽象概念。通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可。
客户端
大多数连接都是可靠的TCP连接。创建TCP连接时,主动发起连接的叫客户端,被动响应连接的叫服务器。
服务器
和客户端编程相比,服务器编程就要复杂一些。
服务器进程首先要绑定一个端口并监听来自其他客户端的连接。如果某个客户端连接过来了,服务器就与该客户端建立Socket连接,随后的通信就靠这个Socket连接了。
所以,服务器会打开固定端口(比如80)监听,每来一个客户端连接,就创建该Socket连接。由于服务器会有大量来自客户端的连接,所以,服务器要能够区分一个Socket连接是和哪个客户端绑定的。一个Socket依赖4项:服务器地址、服务器端口、客户端地址、客户端端口来唯一确定一个Socket。
但是服务器还需要同时响应多个客户端的请求,所以,每个连接都需要一个新的进程或者新的线程来处理,否则,服务器一次就只能服务一个客户端了
1 import socket 2 # 创建一个socket: 3 #family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None 4 #创建Socket时,AF_INET指定使用IPv4协议, 5 # 如果要用更先进的IPv6,就指定为AF_INET6 6 # AF_UNIX Unix不同进程之间的通信 7 # SOCK_STREAM指定使用面向流的TCP协议 SOCK_DGRAPH 8 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 9 print(s) 10 address=(\'127.0.0.1\',8000) 11 #建立连接 12 s.bind(address) 13 #监听设置端口等待客户端的请求数量 14 s.listen(3) 15 16 17 print(\'等待...........\') 18 #accept 阻塞 19 cnn=s.accept() 20 print(cnn)
1 import socket 2 3 sck=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 4 print(sck) 5 address=(\'127.0.0.1\',8000) 6 sck.connect(address)
1 # 流程描述: 2 # 3 # 1 服务器根据地址类型(ipv4,ipv6)、socket类型、协议创建socket 4 # 5 # 2 服务器为socket绑定ip地址和端口号 6 # 7 # 3 服务器socket监听端口号请求,随时准备接收客户端发来的连接,这时候服务器的socket并没有被打开 8 # 9 # 4 客户端创建socket 10 # 11 # 5 客户端打开socket,根据服务器ip地址和端口号试图连接服务器socket 12 # 13 # 6 服务器socket接收到客户端socket请求,被动打开,开始接收客户端请求,直到客户端返回连接信息。这时候socket进入阻塞状态,所谓阻塞即accept()方法一直等到客户端返回连接信息后才返回,开始接收下一个客户端连接请求 14 # 15 # 7 客户端连接成功,向服务器发送连接状态信息 16 # 17 # 8 服务器accept方法返回,连接成功 18 # 19 # 9 客户端向socket写入信息(或服务端向socket写入信息) 20 # 21 # 10 服务器读取信息(客户端读取信息) 22 # 23 # 11 客户端关闭 24 # 25 # 12 服务器端关闭
1 #!/usr/bin/env python3 2 #-*- coding:utf-8 -*- 3 \'\'\' 4 Administrator 5 2018/7/27 6 \'\'\' 7 8 import socket 9 # 创建一个socket: 10 #family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None 11 #创建Socket时,AF_INET指定使用IPv4协议, 12 # 如果要用更先进的IPv6,就指定为AF_INET6 13 # AF_UNIX Unix不同进程之间的通信 14 # SOCK_STREAM指定使用面向流的TCP协议 SOCK_DGRAM UDP协议 15 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 16 print(s) 17 address=(\'127.0.0.1\',8000) 18 #建立连接 19 s.bind(address) 20 #监听设置端口等待客户端的请求数量 21 s.listen(3) 22 23 24 print(\'等待...........\') 25 #accept 阻塞 26 conn,addr=s.accept() 27 28 while True: 29 inp=input(">>>") 30 31 conn.send(("牛郎:>>>"+inp).encode(\'utf-8\')) 32 data=conn.recv(1024) 33 print(data.decode("utf-8"))
1 #!/usr/bin/env python3 2 #-*- coding:utf-8 -*- 3 \'\'\' 4 Administrator 5 2018/7/27 6 \'\'\' 7 import socket 8 9 sck=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 10 print(sck) 11 address=(\'127.0.0.1\',8000) 12 sck.connect(address) 13 while True: 14 data=sck.recv(1024) 15 print(data.decode("utf-8")) 16 17 inp=input(">>>") 18 if inp==\'exit\': 19 break 20 sck.send(("李逵>>>:"+inp).encode(\'utf-8\')) 21 sck.close()
sk.bind(address) #s.bind(address) 将套接字绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组(host,port)的形式表示地址。 sk.listen(backlog) #开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。 #backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5 #这个值不能无限大,因为要在内核中维护连接队列 sk.setblocking(bool) #是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错。 sk.accept() #接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。 #接收TCP 客户的连接(阻塞式)等待连接的到来 sk.connect(address) #连接到address处的套接字。一般,address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。 sk.connect_ex(address) #同上,只不过会有返回值,连接成功时返回 0 ,连接失败时候返回编码,例如:10061 sk.close() #关闭套接字 sk.recv(bufsize[,flag]) #接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。flag提供有关消息的其他信息,通常可以忽略。 sk.recvfrom(bufsize[.flag]) #与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。 sk.send(string[,flag]) #将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。 sk.sendall(string[,flag]) #将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。 #内部通过递归调用send,将所有内容发送出去。 sk.sendto(string[,flag],address) #将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。该函数主要用于UDP协议。 sk.settimeout(timeout) #设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如 client 连接最多等待5s ) sk.getpeername() #返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。 sk.getsockname() #返回套接字自己的地址。通常是一个元组(ipaddr,port) sk.fileno() #套接字的文件描述符
1 #!/usr/bin/env python3 2 #-*- coding:utf-8 -*- 3 \'\'\' 4 Administrator 5 2018/7/27 6 \'\'\' 7 8 import socket 9 # 创建一个socket: 10 #family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None 11 #创建Socket时,AF_INET指定使用IPv4协议, 12 # 如果要用更先进的IPv6,就指定为AF_INET6 13 # AF_UNIX Unix不同进程之间的通信 14 # SOCK_STREAM指定使用面向流的TCP协议 SOCK_DGRAM UDP协议 15 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 16 print(s) 17 address=(\'127.0.0.1\',8000) 18 #建立连接 19 s.bind(address) 20 #监听设置端口等待客户端的请求数量 21 s.listen(3) 22 23 24 print(\'等待...........\') 25 #accept 阻塞 26 conn,addr=s.accept() 27 print(addr) 28 29 30 ###不允许发送空 31 while True: 32 inp=input(">>>") 33 if inp=="q": 34 break 35 conn.send(("牛郎:>>>"+inp).encode(\'utf-8\')) 36 data=conn.recv(1024) 37 if not data: 38 conn.close() 39 conn, addr = s.accept() 40 continue 41 print(data.decode("utf-8"))
1 #!/usr/bin/env python3 2 #-*- coding:utf-8 -*- 3 \'\'\' 4 Administrator 5 2018/7/27 6 \'\'\' 7 import socket 8 9 sck=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 10 print(sck) 11 address=(\'127.0.0.1\',8000) 12 sck.connect(address) 13 while True: 14 data=sck.recv(1024) 15 print(data.decode("utf-8")) 16 17 inp=input(">>>") 18 if inp==\'exit\': 19 break 20 elif not inp: 21 inp="发送空" 22 sck.send(inp.encode(\'utf-8\')) 23 sck.close()
1 import socket 2 # 创建一个socket: 3 #family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None 4 #创建Socket时,AF_INET指定使用IPv4协议, 5 # 如果要用更先进的IPv6,就指定为AF_INET6 6 # AF_UNIX Unix不同进程之间的通信 7 # SOCK_STREAM指定使用面向流的TCP协议 SOCK_DGRAM UDP协议 8 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 9 print(s) 10 address=(\'127.0.0.1\',8000) 11 #建立连接 12 s.bind(address) 13 #监听设置端口等待客户端的请求数量 14 s.listen(3) 15 16 17 print(\'等待...........\') 18 Python入门第三十六天Python丨文件写入