最基础的Python的socket编程入门教程


Posted in Python onApril 23, 2015

本文介绍使用Python进行Socket网络编程,假设读者已经具备了基本的网络编程知识和Python的基本语法知识,本文中的代码如果没有说明则都是运行在Python 3.4下。

Python的socket功能封装在socket库中,要使用socket,记得先import socket,socket库的详细介绍参见官方文档。
创建Socket

首先创建一个socket,使用socket库中得socket函数创建。

import socket
# create an INET, STREAM socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

例子中创建了一个TCP socket,socket.socket函数的前两个参数的默认值是socket.AF_INET和socket.SOCK_STREAM,创建TCP socket时可以直接写成socket.socket()。
连接服务器

使用socket的connect函数连接到服务器,以下几种参数都是合法的。

s.connect(('localhost', 8000))
s.connect(('127.0.0.1', 8000))
s.connect(('www.baidu.com', 80))

发送数据

发送数据有两个方法send和sendall,send不能保证所有的数据都发送完了,它会返回已发送数据的长度,程序要循环发送数据直到所有数据都已发送完毕。

def mysend(s, msg):
  total_len = len(msg)
  total_sent = 0
  while total_sent < total_len:
    sent = s.send(msg[total_sent:])
    if sent == 0:
      raise RuntimeError("socket connection broken")
    total_sent += sent

sendall能够保证所有的数据都已发送完毕,除非发送过程中出现了错误,它实际上也是循环发送数据直到所有数据发送完成。

这里还要讲一个需要特别注意的地方,从一个例子开始吧:

import socket
s = socket.socket()
s.connect(('www.baidu.com', 80))
s.sendall('test')

都是上面讲过的东西,没什么特别的,分别在Python 2和Python 3中执行以上的代码,结果是:

# Python 2.7
>>> import socket
>>> s = socket.socket()
>>> s.connect(('www.baidu.com', 80))
>>> s.sendall('test')

Python 2中执行成功。

# Python 3.4
>>> import socket
>>> s = socket.socket()
>>> s.connect(('www.baidu.com', 80))
>>> s.sendall('test')
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: 'str' does not support the buffer interface

Python 3中却发生了异常。

同样的代码换个环境却不能执行了,我没有写错呀,怒砸电脑。好吧,你确实没写错,是环境变了,导致这个结果的变化请移步官方的说明。
接收数据

使用recv函数接收数据:

data = s.recv(4096)

在Python 3中返回的是bytes对象,在Python 2中返回的是string。注意函数返回的数据长度是小于或者等于参数指定的长度的,要接收到指定长度的数据,需要循环接收数据。

def myreceive(s, msglen):
  chunks = []
  bytes_recd = 0
  while bytes_recd < msglen:
    chunk = s.recv(min(msglen - bytes_recd, 2048))
    if chunk == b'':
      raise RuntimeError("socket connection broken")
    chunks.append(chunk)
    bytes_recd = bytes_recd + len(chunk)
  return b''.join(chunks)

关闭连接

当连接不再需要时可以使用close关闭socket连接,关闭后的连接不能再进行任何操作。当一个socket被回收时会自动关闭,但是不要依赖这种机制,不需要socket时就主动的close。
服务端

服务端程序执行的步骤:
1. 创建服务端socket
1. 将服务端socket绑定到指定的地址和端口
1. 监听连接
1. 接受客户端连接
1. 处理客户端的数据
1. 关闭客户端连接

一个简单的echo server示例:

import socket

HOST = ''
PORT = 10022

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(10)
conn, addr = s.accept()
while True:
  data = conn.recv(1024)
  if not data:
    break
  conn.sendall(data)
conn.close()

客户端程序:

import socket

HOST = 'localhost'
PORT = 10022

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'hello socket')
data = s.recv(1024)
print('Received', repr(data))
s.close()

错误处理

socket处理过程中发生错误会抛出异常,socket相关的异常有:

  • - socket.error
  • - socket.herror
  • - socket.gaierror
  • - socket.timeout
import socket

HOST = None
PORT = 10022

try:
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  s.bind((HOST, PORT))
  s.listen(10)
except: socket.error as msg:
  print(msg)
Python 相关文章推荐
在Python中使用PIL模块处理图像的教程
Apr 29 Python
怎样使用Python脚本日志功能
Aug 14 Python
利用Anaconda完美解决Python 2与python 3的共存问题
May 25 Python
python机器学习之决策树分类详解
Dec 20 Python
Selenium元素的常用操作方法分析
Aug 10 Python
python实现Zabbix-API监控
Sep 17 Python
python采集微信公众号文章
Dec 20 Python
对python中大文件的导入与导出方法详解
Dec 28 Python
Python模拟登入的N种方式(建议收藏)
May 31 Python
keras CNN卷积核可视化,热度图教程
Jun 22 Python
OpenCV实现机器人对物体进行移动跟随的方法实例
Nov 09 Python
如何解决.cuda()加载用时很长的问题
May 24 Python
利用Python实现简单的相似图片搜索的教程
Apr 23 #Python
以911新闻为例演示Python实现数据可视化的教程
Apr 23 #Python
Python中优化NumPy包使用性能的教程
Apr 23 #Python
python通过自定义isnumber函数判断字符串是否为数字的方法
Apr 23 #Python
用Python给文本创立向量空间模型的教程
Apr 23 #Python
用Python进行行为驱动开发的入门教程
Apr 23 #Python
python正常时间和unix时间戳相互转换的方法
Apr 23 #Python
You might like
PHP return语句的另一个作用
2014/07/30 PHP
php实现微信支付之企业付款
2018/05/30 PHP
ExtJS Window 最小化的一种方法
2009/11/18 Javascript
提取字符串中年月日的函数代码
2013/11/05 Javascript
jQuery获取节点和子节点文本的方法
2014/07/22 Javascript
jQuery编程中的一些核心方法简介
2015/08/14 Javascript
JS右下角广告窗口代码(可收缩、展开及关闭)
2015/09/04 Javascript
深入理解JQuery中的事件与动画
2016/05/18 Javascript
js replace(a,b)之替换字符串中所有指定字符的方法
2016/08/17 Javascript
bootstrap模态框跳转到当前模板页面 框消失了而背景存在问题的解决方法
2020/11/30 Javascript
原生js封装添加class,删除class的实例
2017/11/06 Javascript
玩转vue的slot内容分发
2018/09/22 Javascript
解决ng-repeat产生的ng-model中取不到值的问题
2018/10/02 Javascript
vue-cli 打包后提交到线上出现 &quot;Uncaught SyntaxError:Unexpected token&quot; 报错
2018/11/06 Javascript
服务端预渲染之Nuxt(使用篇)
2019/04/08 Javascript
Vue开发Html5微信公众号的步骤
2019/04/11 Javascript
layui对工具条进行选择性的显示方法
2019/09/19 Javascript
基于JS实现简单滑块拼图游戏
2019/10/12 Javascript
vue使用nprogress加载路由进度条的方法
2020/06/04 Javascript
Js实现粘贴上传图片的原理及示例
2020/12/09 Javascript
从零学python系列之浅谈pickle模块封装和拆封数据对象的方法
2014/05/23 Python
详解Python的collections模块中的deque双端队列结构
2016/07/07 Python
Python 操作文件的基本方法总结
2017/08/10 Python
python中set()函数简介及实例解析
2018/01/09 Python
分析Python中解析构建数据知识
2018/01/20 Python
python主线程与子线程的结束顺序实例解析
2019/12/17 Python
Python操作MongoDb数据库流程详解
2020/03/05 Python
django执行原始查询sql,并返回Dict字典例子
2020/04/01 Python
浅谈keras中的Merge层(实现层的相加、相减、相乘实例)
2020/05/23 Python
基于python实现matlab filter函数过程详解
2020/06/08 Python
Python unittest装饰器实现原理及代码
2020/09/08 Python
python Scrapy框架原理解析
2021/01/04 Python
优秀毕业生求职信范文
2014/01/02 职场文书
车贷收入证明范本
2014/09/14 职场文书
会议承办单位欢迎词
2019/07/09 职场文书
Python序列化模块JSON与Pickle
2022/06/05 Python