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 ,连接失败时候返回编码,例如:10061sk.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 socketip_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': breaksk.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 ...
随机推荐
- mui上拉加载
最近在做移动端的项目,用到了mui的上拉加载,整理如下: 1.需要引入的css.js <link rel="stylesheet" href="common/mui ...
- javascript继承详解(待续)
常见继承分两种,一种接口继承,继承方法签名:一种实现继承,继承实际方法.js只支持后一种. 1原型链 首先看原型.构造函数.实例的关系.如果我们让一个函数的原型对象等于另一个的实例,然后另一个的原型对 ...
- 什么是NoSQL
NoSQL = Not Only SQL 不仅仅是SQL NoSQL,指的是非关系型的数据库(没有声明性查询语言,没有预定义的模式,可以为键 - 值对存储,列存储,文档存储,图形数据库).不同于传统的 ...
- rsync远程同步
一.概念 Rsync是一个开源的快速备份工具,可以在不同主机之间镜像同步整个目录树,支持增量备份,保持连接和权限,且采用优化的同步算法,传输前执行压缩,因此非常适用于异地备份,镜像服务器等应用.rsy ...
- 少年,是时候换种更优雅的方式部署你的php代码了
让我们来回忆下上次你是怎么发布你的代码的: 1. 先把线上的代码用ftp备份下来 2. 上传修改了的文件 3. 测试一下功能是否正常 4. 网站500了,赶紧用备份替换回去 5. 替换错了/替换漏了 ...
- Angular2.js——主从结构
学习这一篇的内容,还回到我们快速起步的应用上来. 主从结构,我们想要做一个英雄的列表,我们希望用户在列表中选中一个英雄,然后这个被选中的英雄出现在详情视图中.主视图是英雄列表,从视图则是被选中英雄的详 ...
- Linux IO barrier
I/O顺序问题是一个比较综合的问题,它涉及的层次比较多,从VFS page cache到I/O调度算法,从IO子系统到存储外设.而Linux I/O barrier就是其中重要的一部分. 可能很多人认 ...
- SublimeText3编译JavaScript
这个操作很简单总的来说分为两步,1.安装Node.js 2.添加SublimeText3 JS编译系统 首先我们去官网下载node.js https://nodejs.org/en/ 然后安装 验证 ...
- C# Winform中的窗体传值
关于C#winform窗体之间的传值有以下几种做法 1 通过构造函数传值 2 属性传值 以上两种方法不早详细介绍. 3 通过事件传值,委托传值 首先看一下通过委托传值吧. 1,创建两个窗体,分别是Fo ...
- 做自己的PHP语法解释器
PHP关键字异构化实验 PHP词法分析和语法分析 简单理解PHP代码执行过程:http://blog.csdn.net/risingsun001/article/details/22888861 PH ...