Python网络编程(1)-socket
我会在近期尽快更新好之前写的博客,会添加新的知识点和注意问题,排版和内容都会较之前有很大的改观,感谢大家一直的支持!
1、 客户端/服务器架构
客户端/服务器架构也称主从式架构,简称C/S架构,它是一种网络结构,把客户端(Client)(通常是一个采用图形界面的程序)与服务器(server)区分开来,在C/S架构中,服务器是一系列的硬件或软件,客户端是提交服务请求的用户,客户端提供用户请求接口,服务端响应请求进行对应的处理,并返回给客户端。客户端/服务器架构既可以应用于计算机硬件,也可以应用于软件。
1.1、 硬件客户端/服务器架构
典型的硬件客户端/服务器架构就是打印机,在企业中,员工通过局域网将个人电脑连接到打印机上,作为客户端向打印机发送打印请求,打印机作为服务端完成响应处理相应的请求。
1.2、 软件客户端/服务器架构
软件服务器也是运行在硬件之上的,典型的软件服务器是Web服务器。在一台或多台电脑上搭建Web服务器,以提供用户访问所需的Web页面和应用程序,Web服务器一旦启动,都将可能永远运行,除非受到一些外力驱使才会停止,如人为关闭,服务器硬件故障等。它的工作就是接收客户端的请求,并响应请求给客户端返回相应的Web页面,然后等待下一个客户端的请求。
2、 套接字
套接字是网络编程中的一个基本组件,如果想要服务器能够响应客户端发来的请求,首先要建立一个通信端点,使服务器能够监听服务,当通信端点建立后,就会进入无限循环的等待请求状态,当接收到客户端的请求,就会响应该请求。
套接字就是两个程序之间的信息通道,可以理解为上面提到的“通信端点”的概念。在通信开始之前,网络应用程序必须创建套接字。套接字是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口号,远程主机的IP地址,远程进程的协议端口号。
套接字起源于 20 世纪 70 年代,它是加利福尼亚大学伯克利分校版本的 Unix的一部分,即人们所说的 BSD Unix。 因此,套接字也被人们称为“伯克利套接字”或“BSD 套接字”。套接字最初被设计用于同一台主机上多个应用程序之间的通讯,这也就是所谓的进程间通讯(IPC)。
TCP用主机的IP地址加上主机的端口号作为TCP连接的端点,这种端点就叫做套接字(socket)或插口。套接字用(IP地址:端口号)表示。
套接字有两种类型,分别是基于文件的和基于网络的。
基于文件的套接字家族名字叫做“AF_UNIX”,代表地址家族(address family):UNIX。在Unix和linux操作系统中,熟为人知的一句话就是:一切皆文件,一个或多个进程运行在同一台机器上,所以套接字是基于文件的,它就可以通过访问底层的基础结构来实现进程之间的通信
基于网络的套接字家族名字叫做“AF_INET”,代表地址家族(address family):INET(因特网)。它使用IPv4进行通信,因为IPv4使用32位地址,相比于IPv6的128位来说,计算更快,更适合于局域网的通信。目前它也是使用最广泛的。
在本文中,重点讲网络编程,所以在后面的涉及最多的还是AF_INET。
2.1、 流式套接字(SOCK_STREAM)
不论使用哪种地址家族,都只有两种套接字的连接方式,一种是面向连接的,一种是无连接的。
面向连接的套接字连接方式,意味着在进程通信之前必须先建立好一个连接,这种套接字就称为流式套接字。
流式套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复发送,并按顺序接收。流式套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即TCP(The Transmission Control Protocol)协议。在Python中,创建TCP套接字,就必须声明SOCK_STREAM作为套接字类型。
2.2、 数据报套接字(SOCK_DGRAM)
数据报套接字提供了一种无连接的服务。这也意味着,使用这种连接方式不需要在进程通信前建立连接。在数据的传输过程中,SOCK_DGRAM并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP(User Datagram Protocol)协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。
虽然存在数据丢失、重复、数据无序接受等很多缺点,但它也有优势所在,在流式套接字中,因为是面向连接并提供了可靠的数据传输服务,这对于虚拟电路连接的维护需要很大的开销,但数据报套接字就不需要这些额外的开销,所以维护、资源占用成本更低。
3、 网络编程
Python是一个很强大的网络编程工具,Python内有很多针对网络协议的库,这些库对网络协议的各个层次进行抽象封装,这对于程序员来说就意味着:不必关心网络协议的原理,只需要通过对程序的逻辑处理,就可以实现网络数据的传输。
3.1、 创建套接字
在Python中,创建套接字需要使用socket模块,通过socket()函数创建套接字对象。
class socket(_socket.socket):
-- skip --
def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None):
-- skip --
从socket函数的的构造方法中可以看出,可以指定地址家族和套接字的连接方式,proto默认是0,通常都省略。即创建套接字对象的时候:
import socket
#创建TCP/IP套接字,地址家族AF_INET
tcp_socket = socket.socket(socket.AF_INET,socket.SOCKET_STREAM)
#创建UDP/IP套接字,地址家族AF_INET
udp_socket = socket.socket(socket.AF_INET,socket.SOCKET_DGRAM)
3.2、 套接字的内置方法
常见的套接字内置函数
方法 |
功能 |
st.recv() |
接受TCP的消息 |
st.recv_into() |
接受TCP的消息到指定的缓存区 |
st.send() |
发送TCP的消息(当待发送的消息量大于缓存区剩余内存时,数据会丢失) |
st.sendall() |
完整的发送TCP消息(当待发送的消息量大于缓存区剩余内存时,数据不会丢失,循环调用send 直到发完为止) |
st.recvfrom() |
接收UDP的消息 |
st.recvfrom_into() |
接收UDP的消息到指定的缓存区 |
st.sendto() |
发送UDP的消息 |
st.getpeername() |
连接到套接字的远程地址(TCP) |
st.getsockname() |
获取当前套接字的地址 |
st.getsockopt() |
获取指定套接字的参数 |
st.setsockopt() |
设置指定套接字的参数 |
st.close() |
关闭套接字 |
st.shutdown() |
关闭连接 |
服务端套接字方法
方法 |
功能 |
st.bind() |
将IP地址+端口号绑定到套接字上 |
st.listen() |
开启TCP监听功能 |
st.accept() |
被动的接受TCP客户端的连接,(阻塞式)一直等待连接直到连接到达 |
客户端套接字方法
方法 |
功能 |
st.connect() |
主动发起TCP服务器连接 |
st.connect_ex() |
connect()的扩展版本,以错误代码的形式返回问题,而不是抛出异常 |
面向阻塞的套接字方法
方法 |
功能 |
st.setblocking() |
设置套接字为阻塞模式或非阻塞模式 |
st.settimeout() |
设置阻塞套接字的操作超时时间 |
st.gettimoout() |
获取阻塞套接字的操作超时时间 |
面向文件的套接字方法
方法 |
功能 |
st.fileno() |
套接字的文件描述符 |
st.makefile() |
创建与套接字相关联的文件对象 |
数据属性
属性 |
功能 |
st.family |
套接字家族 |
st.type |
套接字类型 |
st.proto |
套接字协议 |
3.3、 Tcp服务器和客户端的通信
上面提到过,套接字对象都是通过socket.socket()函数来创建的,下面模拟一个TCP服务器和客户端,来实现进程间的通信。
Tcp服务端:
import socket
tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) //创建服务器套接字
tcp_server.bind(("127.0.0.1",8000)) //将套接字与地址绑定
tcp_server.listen(5) //建立监听连接
print("The server has started")
while True:
conn,addr= tcp_server.accept() //接受客户端的连接
while True:
try:
data = conn.recv(1024) //会话的接收(或发送)
print("msg is",data.decode("utf-8")) //要将收到的会话数据进行解码
conn.send(data.title()) //会话的发送(或接受)
except Exception:
break
conn.close() //关闭连接
tcp_server.close() //关闭服务器套接字
在Tcp服务端,先创建服务器套接字并指定类型为流式套接字(SOCK_STREAM)。因为服务器需要占用一个端口并等待客户端的请求,所以它们必须绑定到一个本地地址。Tcp是一种面向连接的通信方式,所以必须建立监听连接,listen(5)的意义是允许传入连接的最大数为5个。当调用accept()函数后,服务端就会进入一个等待状态,默认情况下,accept()处于阻塞状态,也就意味着,执行到此处,程序会暂停,直到有新的连接到达,才会进行下一步的收发操作。
Tcp客户端:
import socket
tcp_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) //创建客户端套接字
tcp_client.connect(("127.0.0.1",8000)) //连接服务器
while True:
msg = input("Please input your message:").strip()
if not msg:continue
tcp_client.send(msg.encode("utf-8")) //会话接收(或发送)
data = tcp_client.recv(1024)
print("reply is",data.decode("utf-8"))
tcp_client.close() //关闭客户端套接字
创建客户端比服务端要简单很多,客户端一旦拥有了套接字,就可以利用套接字的connect()方法直接创建一个服务器的连接,建立好连接,就可以参与到服务端的会话中,当客户端的需求全部完成,就会关闭套接字,终止此次连接。
3.4、 Udp服务端和客户端的通信
Udp服务器不需要Tcp服务器那么多的配置,因为它不是面向连接的,除了等待传入的连接,它基本不需要其他的操作。
Udp服务端:
import socket
ip_port = ("127.0.0.1",8000)
udp_server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) //创建服务端套接字
udp_server.bind(ip_port) //绑定本地地址
print("the server has started")
while True:
data,addr = udp_server.recvfrom(1024) //关闭接收(或发送)
print(data)
udp_server.sendto(data.title(),addr) //关闭发送(或接受)
从上面代码中可以看出,除了创建套接字并绑定本地地址后,基本
没有其它的操作,它是无连接的,这也就意味着,它无需为了成功通信而使一个客户端连接到一个“特定”的套接字进行转换操作,服务器端仅仅是接收数据并进行回复。
Udp客户端:
import socket
ip_port = ("127.0.0.1",8000)
udp_client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) //创建服务端套接字
while True:
msg = input(">>>").strip()
udp_client.sendto(msg.encode("utf-8"),ip_port) //发送
data,addr = udp_client.recvfrom(1024) //接收
print(data)
udp_client.close() //关闭套接字
Udp客户端,一旦创建了套接字,就可以进行会话循环中,当会话结束,关闭套接字。
在使用Udp进行通信的时候,服务端可以同时接收多个客户端的会话请求并返回请求结果。
Python网络编程(1)-socket的更多相关文章
- python 网络编程:socket(二)
上节地址:Python网络编程:socket 一.send和sendall区别 send,sendall ret = send('safagsgdsegsdgew') #send 发送 ...
- python 网络编程(Socket)
# from wsgiref.simple_server import make_server## def RunServer(environ,start_response):# start_resp ...
- python 网络编程:socket
在学习socket之前,我们先复习下相关的网络知识. OSI七层模型:应用层,表示层,会话层,传输层,网络层,数据链路层,物理层.OSI七层模型是由国际标准化组织ISO定义的网络的基本结构,不仅包括一 ...
- python网络编程:socket套接字
一.socket 二.TCP服务器 三.TCP客户端 四.UDP服务器 五.UDP客户端 六.聊天的客户端 七.聊天的服务器 一.socket """ 学习网络编程 其实 ...
- Python 网络编程和Socket
2017-07-24 20:43:49 Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求.Http协议主要的操作流程是req ...
- Python学习:20.Python网络编程(Socket)
一.Socket介绍 我们知道两个进程如果需要进行通讯,最基本的一个前提是能够唯一标示一个进程.在本地进程通讯中可以使用PID来唯一标示一个进程,但PID只在本地唯一,网络中的两个进程PID冲突几率很 ...
- Python网络编程(socket模块、缓冲区、http协议)
网络的概念:主机 端口 IP 协议 服务器: localhost/127.0.0.1 客户端: 只是在本机启动客户端,用127.0.0.1访问 服务器: 0.0.0.0 客户端: ...
- python | 网络编程(socket、udp、tcp)
一.套接字 socket 1.1 作用:实现不同主机间的进程间通信(不同电脑.手机等设备之间收发数据) 1.2 分类:udp.tcp 1.3 创建 socket import socket socke ...
- python网络编程:socket半连接池、UDP通讯模板
一.TCP半连接池原理 二.UDP通讯 三.UDP聊天 四.UDP聊天2 五.UDP会粘包吗 六.UDP总结 七.UDP与TCP对比 一.TCP半连接池原理 客户端 import socket cli ...
- python网络编程-01
python网络编程 1.socket模块介绍 ①在网络编程中的一个基本组件就是套接字(socket),socket是两个程序之间的“信息通道”. ②套接字包括两个部分:服务器套接字.客户机套接字 ③ ...
随机推荐
- Web API <五> 序列化
在 Asp.Net Web Api 中提供了两种 媒体类型格式化器(mime-type formatter),分别用于支持 JSON 和 XML 数据的格式化处理.默认两种格式化器已集成到了 Asp. ...
- ios 积累
1.加号 是可以通过类名直接调用这个方法,而减号则要实例化逸个对象,然后通过实例化的对象来调用该方法!! 2.(返回类型) 方法名 :(参数类型)变量名 空格 参数二名 :(参数类型) 变量名 空格 ...
- ThinkPhp关闭Debug后出错解决方案
注:我使用的是ThinkPHP的3.2版本,其他版本类似 从自己入手PHP开发以来,一直使用的是ThinkPHP的框架,前几天偶然间碰到了一个错误,在Debug模式下网站一切正常,而关闭Debug进行 ...
- mybatis-pageHelper做分页
Mybatis-PageHelpera是一个很好的第三方分页插件,支持很多数据库,几乎主流的数据库都支持 github地址:https://github.com/pagehelper/Mybatis- ...
- python_如何为元组中每个元素命名
学生信息系统: (名字,年龄,性别,邮箱地址) 为了减少存储开支,每个学生的信息都以一个元组形式存放 如: ('tom', 18,'male','tom@qq.com' ) ('jom', 18,'m ...
- BSA Network Shell系列-nexec | runcmd | runscript | scriptutil的异同
说明下nexec.runcmd.runscript.scriptutil的异同 相同点: 四者都可以在远程机器执行命令.或者调用脚本. 不同点: nexec支持NSH命令,可以执行远程机的本地命令(非 ...
- 更改Patrol Agent的密码
大家可以使用P3console去做,具体方法请见:http://wenku.baidu.com/link?url=HbSzxNV2SPrlpk_Bfmcg0CNZuAlyX4jgdp4vbrxmynv ...
- nodejs爬虫笔记(一)---request与cheerio等模块的应用
目标:爬取慕课网里面一个教程的视频信息,并将其存入mysql数据库.以http://www.imooc.com/learn/857为例. 一.工具 1.安装nodejs:(操作系统环境:WiN 7 6 ...
- matlab输入输出语句(input、disp、fprintf)
输入语句 输入数值 ?x=input('please input a number:') please input a number:22 x = 22 输入字符串 ?x=input('please ...
- Nagios在selinux开启的情况下使用
# chcon -R -t httpd_sys_content_t /usr/local/nagios/sbin/ # chcon -R -t httpd_sys_content_t /usr/loc ...