python之路 socket,socketsever初探
socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一 般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原 意那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务
2、连接原理
根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。
(1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
(2)客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
(3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接 字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
案例
1、最简单的web服务器
- #!/usr/bin/env python
- #coding:utf-8
- #导入socket模块
- import socket
- #开启ip和端口
- ip_port = ('127.0.0.1',8080)
- #生成句柄
- web = socket.socket()
- #绑定端口
- web.bind(ip_port)
- #最多连接数
- web.listen(5)
- #等待信息
- print ('nginx waiting...')
- #开启死循环
- while True:
- #阻塞
- conn,addr = web.accept()
- #获取客户端请求数据
- data = conn.recv(1024)
- #打印接受数据 注:当浏览器访问的时候,接受的数据的浏览器的信息等。
- print(data)
- #向对方发送数据
- conn.send(bytes('<h1>welcome nginx</h1>','utf8'))
- #关闭链接
- conn.close()
1)service端
- #!/usr/bin/env python
- #coding:utf-8
- import socket
- #开启ip和端口
- ip_port = ('127.0.0.1',9999)
- #生成一个句柄
- sk = socket.socket()
- #绑定ip端口
- sk.bind(ip_port)
- #最多连接数
- sk.listen(5)
- #开启死循环
- while True:
- print ('server waiting...')
- #等待链接,阻塞,直到渠道链接 conn打开一个新的对象 专门给当前链接的客户端 addr是ip地址
- conn,addr = sk.accept()
- #获取客户端请求数据
- client_data = conn.recv(1024)
- #打印对方的数据
- print (str(client_data,'utf8'))
- #向对方发送数据
- conn.sendall(bytes('不要回答,不要回答,不要回答','utf8'))
- #关闭链接
- conn.close()
(2)client端
- #!/usr/bin/env python
- #coding:utf-8
- import socket
- #链接服务端ip和端口
- ip_port = ('127.0.0.1',9999)
- #生成一个句柄
- sk = socket.socket()
- #请求连接服务端
- sk.connect(ip_port)
- #发送数据
- sk.sendall(bytes('yaoyao','utf8'))
- #接受数据
- server_reply = sk.recv(1024)
- #打印接受的数据
- print (str(server_reply,'utf8'))
- #关闭连接
- sk.close()
3、更多功能
更多功能
sk
=
socket.socket(socket.AF_INET,socket.SOCK_STREAM,
0
)
参数一:地址簇
socket.AF_INET IPv4(默认)
socket.AF_INET6 IPv6
socket.AF_UNIX 只能够用于单一的Unix系统进程间通信
参数二:类型
socket.SOCK_STREAM 流式socket ,
for
TCP (默认)
socket.SOCK_DGRAM 数据报式socket ,
for
UDP
socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而
SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以
通过IP_HDRINCL套接字选项由用户构造IP头。
socket.SOCK_RDM 是一种可靠的UDP形式,即保证交付数据报但不保证顺序。
SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,
如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。
socket.SOCK_SEQPACKET 可靠的连续数据包服务
参数三:协议
0
(默认)与特定的地址家族相关的协议,如果是
0
,
则系统就会根据地址格式和套接类别,自动选择一个合适的协议
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()
套接字的文件描述符
二、socket server
SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,从而实现并发处理多个客户端请求的Socket服务端。即:每个客户端请求连接到服务器时,Socket服务端都会在服务器是创建一个“线程”或者“进 程” 专门负责处理当前客户端的所有请求。
注:导入模块的时候 3.x版本是socketserver 2.x版本是SocketServer
1.ThreadingTCPServer
ThreadingTCPServer实现的Soket服务器内部会为每个client创建一个 “线程”,该线程用来和客户端进行交互。
ThreadingTCPServer基础
使用ThreadingTCPServer:
创建一个继承自 SocketServer.BaseRequestHandler 的类
类中必须定义一个名称为 handle 的方法
启动ThreadingTCPServer
服务端
- import SocketServer
- class MyServer(SocketServer.BaseRequestHandler):
- def handle(self):
- conn = self.request
- conn.sendall('我是多线程')
- Flag = True
- while Flag:
- data = conn.recv(1024)
- if data == 'exit':
- Flag = False
- elif data == '0':
- conn.sendall('您输入的是0')
- else:
- conn.sendall('请重新输入.')
- if __name__ == '__main__':
- server = SocketServer.ThreadingTCPServer(('127.0.0.1',8009),MyServer)
- server.serve_forever()
客户端
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import
socket
ip_port
=
(
'127.0.0.1'
,
8009
)
sk
=
socket.socket()
sk.connect(ip_port)
while
True
:
data
=
sk.recv(
1024
)
print
'receive:'
,data
inp
=
input
(
'please input:'
)
sk.sendallinp)
if
inp
=
=
'exit'
:
break
sk.close()
内部调用流程为:
- 启动服务端程序
- 执行 TCPServer.init 方法,创建服务端Socket对象并绑定 IP 和 端口
- 执行 BaseServer.init 方法,将自定义的继承自SocketServer.BaseRequestHandler 的类 - MyRequestHandle赋值给 self.RequestHandlerClass
- 执行 BaseServer.server_forever 方法,While 循环一直监听是否有客户端请求到达 ...
当客户端连接到达服务器 - 执行 ThreadingMixIn.process_request 方法,创建一个 “线程” 用来处理请求
- 执行 ThreadingMixIn.process_request_thread 方法
- 执行 BaseServer.finish_request 方法,执行 self.RequestHandlerClass() 即:执行 自定义 MyRequestHandler 的构造方法(自动调用基类BaseRequestHandler的构造方法,在该构造方法中又会调用 MyRequestHandler的handle方法)
ForkingTCPServer
ForkingTCPServer和ThreadingTCPServer的使用和执行流程基本一致,只不过在内部分别为请求者建立 “线程” 和 “进程”。
python之路 socket,socketsever初探的更多相关文章
- Python之路 - Socket实现远程执行命令
Python之路 - Socket实现远程执行命令 os模块实现
- Python之路 - Socket实现QQ聊天
Python之路 - Socket实现QQ聊天 介绍
- python之路 socket、socket server
一.socket socket的英文原义是“孔”或“插座”.作为BSD UNIX的进程通信机制,取后一种意思.通常也 称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可 ...
- 百万年薪python之路 -- Socket
Socket 1. 为什么学习socket 你自己现在完全可以写一些小程序了,但是前面的学习和练习,我们写的代码都是在自己的电脑上运行的,虽然我们学过了模块引入,文件引入import等等,我可以在程序 ...
- 百万年薪python之路 -- socket粘包问题解决
socket粘包问题解决 1. 高大上版解决粘包方式(自定制包头) 整体的流程解释 整个流程的大致解释: 我们可以把报头做成字典,字典里包含将要发送的真实数据的描述信息(大小啊之类的),然后json序 ...
- 百万年薪python之路 -- socket()模块的用法
socket()模块的用法: import socket socket.socket(socket_family,socket_type,protocal=0) socket_family 可以是 A ...
- Python之路【第六篇】:socket
Python之路[第六篇]:socket Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字&quo ...
- Python之路,Day8 - Socket编程进阶
Python之路,Day8 - Socket编程进阶 本节内容: Socket语法及相关 SocketServer实现多并发 Socket语法及相关 socket概念 socket本质上就是在2台 ...
- Python学习之路--Socket
Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...
随机推荐
- 这个demo是为解决IQKeyboardManager和Masonry同时使用时,导航栏上移和make.right失效的问题
原文链接在我的个人博客主页 (一).引言: 在 IQKeyboardManager 和 Masonry 同时使用时,导航栏上移和make.right失效等问题多多. 其实我们完美的效果应该是这样的:* ...
- 通过修改CoreCLR中的ClrHost实现自托管程序
上一篇我们讲了如何在windows和Linux上编译CoreClr的问题 虽然文章使用的是windows 10 (Bash)环境,但是也可以做为ubuntu环境的参考. 成功编译CoreCLR的源代码 ...
- webapp 1px显示两倍的问题
公司最近换新首页,按照设计师的要求<大家都在逛>的分割线要1个像素. .span-3{ width:33.3333%; &:not(:first-child){ &:bef ...
- sphinx全文检索引擎
今天刚刚学习了一下,就直接分享上去,有些还没有接触,如果有问题请指正,谢谢 sphinx是什么? Sphinx是一个全文检索引擎.主要为其他应用提供高速.低空间占用.高结果 相关度的全文搜索功能. S ...
- LeetCode 108: Convert Sorted Array to Binary Search Tree DFS求解
Given an array where elements are sorted in ascending order, convert it to a height balanced BST. 解题 ...
- iOS模式详解—「runtime面试、工作」看我就 🐒 了 ^_^.
Write in the first[写在最前] 对于从事 iOS 开发人员来说,当提到 ** runtime时,我想都可以说出来 「runtime 运行时」和基本使用的方法.相信很多开发者跟我当初一 ...
- Python-3------新年考试周的Python学习
2016一开始就是考试周,准备专业课的考试复习.每天上午复习,晚上复习到8点半,之后到10点这点时间来看Python.庆幸没有在忙碌的时候荒废 Python的学习. 期待寒假,以前寒假在家总是没事做, ...
- 个人VIM配置实例
用户 vimrc 文件: "$HOME/.vimrc" " vimrc by lewiyon@hotmail.com " last update 2013-10 ...
- JavaScript中var变量引用function与直接声明function
今天在h5开发app的过程中遇到了一个js问题,function的执行问题 在js中声明函数function有这两种方法 var A=function(){...} 或者 function A(){. ...
- CentOS 7安装Docker
在虚拟机CentOS 7上安装Docker ## 零:检查前提条件: 在Red Hat 和Red Hat系列的Linux发行版中,安装Docker所需的前提提交并不多. ### 1.内 ...