Socket通信的Python实现
Python中实现socket通信,socket通信的服务端比较复杂,而客户端非常简单,所以客户端基本上都是用sockct模块实现,而服务
端用有很多模块可以使用。下面就说一下服务端可使用的模块。
| 模块名 | 简介 | 使用情况 |
|---|---|---|
| socket | 最原始,最低端的模块,如果你想亲自体验socket的整个实现过程,那就用它吧 | 不用 |
| SocketServer | 它把socket的实现进行了很好的封装,比如server端要为每个TCP连接创建一个新的线程/进程等等,这些你不用关心,它会帮你搞定,用户的主要工作是写已连接TCP/UDP的处理方法handle() | 比较常用 |
| select | 在一个线程/进程中同时监控处理多个已连接好的socket | 比较常用 |
| Twisted | 很牛逼的一个模块,功能很强大,已经算是一个框架了 | 比较常用 |
| 其它异步框架 |
如gevent等 |
比较常用 |
下面用上面几个常用的模块实现TCP类型socket通信:Client端发送字符串,Server端收到后在数据前加处理线程/进程的id返回,Client端收到后打
印出来。Client端如果输入的是空字符,那就关闭Client的socket,接着结束该Client进程(它会触发Server端对应的connected_socket.recv()返回空
字符串,关闭connect_sock。以下都是在Windows上运行通过。如果想结束server或client端,那就直接kill就行了,它会自动释放占用的所有资源。
1、使用socket模块
Server(多线程实现)
在Winows下,子进程的入口参数不是能有socket类对象,详见http://bugs.python.org/issue11119,所以要想实现多进程比较麻烦;而Linux上没
有这个问题,在下面代码的基础上很小的修改就行实现。Server端监听TCP连接,对于建立好的每个连接,监听进程为其创建一个线程/进程,并检测线程/
进程的状态,如果已结束,那就进行收尾工作。监听进程使用的是非阻塞Socket(不是立即返回,有超时),这是因为监听进程除了处理新连接之外还要检
查子进程的状态。如果设定成阻塞,那它将所有已建立的连接POP出来由交由子线程后,就会一直阻塞在accept(),如果一直没有新的已建立好的连接,那它
就会一直阻塞下去,就没有办法检测子线程的状态了。所以为了既能检查已建立的连接队列又能检查子进程的状态,需把该socket设置成非阻塞。handle()是
为每个建立好的连接创建的子线程的入口。
#-*- coding:utf-8 -*- import socket
import threading BUFSIZE = 1024
def handle(connected_sock):
while True:
data = connected_sock.recv(BUFSIZE)
if len(data) >0:
print 'receive:',data
cur_thread = threading.current_thread()
send_data = '{}:{}'.format(cur_thread.ident,data)
connected_sock.sendall(send_data) #用sendall,不要用send,send并不一定发送所有send_data,可能发送了部分就返回了
print 'send:',send_data
else:
print 'close the connected socket and terminate sub thread'
connected_sock.close()
break HOST = ''
PORT = 12356
ADDR = (HOST,PORT)
sub_threads = [] listen_sock = socket.socket()
listen_sock.settimeout(5.0) #设定超时时间后,socket其实内部变成了非阻塞,但有一个超时时间
listen_sock.bind(ADDR)
listen_sock.listen(2)
print 'build connect when new TCP comes' while True:
try:
connected_sock,client_addr = listen_sock.accept()
except socket.timeout:
length = len(sub_threads)
while length:
sub = sub_threads.pop(0)
sub_id = sub.ident #进程ID
sub.join(0.1) #等待线程结束,0.1秒
if sub.isAlive():
sub_threads.append(sub)
else:
print 'killed sub thread ',sub_id
length -=1
else:
t = threading.Thread(target=handle,name='sub thread',args=(connected_sock,))
#它继承了listen_socket的阻塞/非阻塞特性,因为listen_socket是非阻塞的,所以它也是非阻塞的
#要让他变为阻塞,所以要调用setblocking
connected_sock.setblocking(1)
t.start()
sub_threads.append(t)
Client端
#-*- coding:utf-8 -*- import socket
HOST = 'localhost'
PORT = 12356
ADDR =(HOST,PORT)
BUFSIZE = 1024 sock = socket.socket()
try:
a = sock.connect(ADDR)
except Exception,e:
print 'error',e
sock.close()
sys.exit() print 'have connected with server' while True:
data = raw_input('> ')
if len(data)>0:
print 'send:',data
sock.sendall(data) #不要用send()
recv_data = sock.recv(BUFSIZE)
print 'receive::',recv_data
else:
sock.close()
break
2、SocketServer模块
Server(多线程实现,Linux下建议用多进程)
在Linux上可以用多进程实现,基本上把下面代码中的ThreadingTCPServer改为ForkingTCPServer就可以了。在Windows下无法用多进程,因为
SocketServer为每个已连接创建进程时,用的是os.fork(),windows上没有fork() API,哎,干嘛不搞个兼容Windows的API啊。
可以看到,下面的代码非常简洁,用户不用去子线程的结束后,父进程对它的收尾,也不用关心socket的关闭。这些都由SocketServer完成。
Handler中的handle()方法与上面用socket模块写的handle方法基本相同。
#-*- coding:utf-8 -*-
from SocketServer import BaseRequestHandler,ThreadingTCPServer
import threading BUF_SIZE=1024 class Handler(BaseRequestHandler):
def handle(self):
while True:
data = self.request.recv(BUF_SIZE)
if len(data)>0:
print 'receive=',data
cur_thread = threading.current_thread()
response = '{}:{}'.format(cur_thread.ident,data)
self.request.sendall(response)
print 'send:',response
else:
print 'close'
break if __name__ == '__main__':
HOST = ''
PORT = 12356
ADDR = (HOST,PORT)
server = ThreadingTCPServers(ADDR,Handler) #参数为监听地址和已建立连接的处理类
print 'listening'
server.serve_forever() #监听,建立好TCP连接后,为该连接创建新的socket和线程,并由处理类中的handle方法处理
Socket通信的Python实现的更多相关文章
- Python Socket通信原理
[Python之旅]第五篇(一):Python Socket通信原理 python Socket 通信理论 socket例子 摘要: 只要和网络服务涉及的,就离不开Socket以及Socket编 ...
- Python简易聊天工具-基于异步Socket通信
继续学习Python中,最近看书<Python基础教程>中的虚拟茶话会项目,觉得很有意思,自己敲了一遍,受益匪浅,同时记录一下. 主要用到异步socket服务客户端和服务器模块asynco ...
- Python进阶----UDP协议使用socket通信,socketserver模块实现并发
Python进阶----UDP协议使用socket通信,socketserver模块实现并发 一丶基于UDP协议的socket 实现UDP协议传输数据 代码如下:
- python - socket通信笔记
参考: 通过编写聊天程序来熟悉python中多线程和socket的用法:https://www.cnblogs.com/mingjiatang/p/4905395.html python socket ...
- 【Socket通信】关于Socket通信原理解析及python实现
Socket(套接字)通信{网络通信其实就是Socket间的通信},首先了解下概念:[来源于百度百科] "两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket.& ...
- python udp socket通信
前段时间学习了一下c++的socket通信,但发现那玩意儿比较复杂还是转向python了,下面就是一个简单的udpsocket通信程序,欢迎大佬前来指正 udp聊天 import socket # 创 ...
- 【转】Python学习---Socket通信原理以及三次握手和四次挥手详解
[原文]https://www.toutiao.com/i6566024355082404365/ 什么是Socket? Socket的中文翻译过来就是"套接字".套接字是什么,我 ...
- Python socket 通信功能简介
常用的地址家族AF_UNIX:基于文件,实现同一主机不同进程之间的通信AF_INET:基于网络,适用于IPv4AF_INET6:基于网络,使用于IPv6 常见的连接类型SOCK_STREAM:即TCP ...
- Day 6-2简单的socket通信
什么是socket? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面 ...
随机推荐
- Android开发-- 使用ADT23 的一些问题
在使用最新版ADT 23进行android学习时发现一些问题: 1.通过设置intent的action来启动另外一个activity时,会出现No Activity found to handle I ...
- osgearth缓存数据命令
新建一个.bat文件 中国地区 osgearth_package.exe ReadyMap.earth --tms ReadyMap.earth --out D:\APICenter\EarthDat ...
- 安装.NET Framework 3.5
https://www.microsoft.com/zh-CN/download/details.aspx?id=22 https://docs.microsoft.com/zh-cn/dotnet/ ...
- 【.netcore学习】.netcore添加到 supervisor 守护进程自启动报错
配置 supervisor [program:HelloWebApp] command=dotnet run directory=/home/python/dotnet/myweb/mywebapi ...
- 【WEB前端系列之CSS】CSS3动画之Transform
前言 Transform字面上是变形,改变的意思,在CSS3中transform主要包括如下几种 旋转rotate 扭曲skew 缩放scale 移动translate 矩形变形matrix tran ...
- 解决:SqlDateTime 溢出。必须介于 1/1/1753 12:00:00 AM 和 12/31/9999 11:59:59 PM 之间提示问题
提示信息如下 “/”应用程序中的服务器错误. SqlDateTime 溢出.必须介于 1/1/1753 12:00:00 AM 和 12/31/9999 11:59:59 PM 之间. 问题现象: 问 ...
- [原]openstack-kilo--issue(二) openstack auth error
/** 系统环境:redhat7.2 repo:163 openstack version : kilo author: lihaibo 本博客已经添加"打赏"功能,"打 ...
- Rsync未授权访问漏洞的利用和防御
首先Rsync未授权访问利用 该漏洞最大的隐患在于写权限的开启,一旦开启了写权限,用户就可以,用户就可以利用该权限写马或者写一句话,从而拿到shell. 我们具体来看配置文件的网相关选项(/etc/r ...
- VB学习之路基础(一)
1.VB不区分大小定,VB编辑器会自动更正. 2.每一行代码语句,没有语句结束符. 3.续行符:一个"空格"加上一个"下划线".不能在参数中间加续行符. 5.合 ...
- [转][darkbaby]任天堂传——失落的泰坦王朝(上)
前言: 曾经一再的询问自我;是否真的完全了解任天堂这个游戏老铺的真实本质?或许从来就没有人能够了解,世间已经有太多的真相被埋没在谎言和臆测之中.作为 一个十多年游龄的老玩家,亲眼目睹了任天堂从如日 ...