最基础的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 代码性能优化技巧分享
Aug 07 Python
Python Property属性的2种用法
Jun 21 Python
Python二叉树的遍历操作示例【前序遍历,中序遍历,后序遍历,层序遍历】
Dec 24 Python
python 字典操作提取key,value的方法
Jun 26 Python
Python高级特性 切片 迭代解析
Aug 23 Python
Python 通过截图匹配原图中的位置(opencv)实例
Aug 27 Python
用Python解数独的方法示例
Oct 24 Python
Python3 使用map()批量的转换数据类型,如str转float的实现
Nov 29 Python
python飞机大战pygame游戏背景设计详解
Dec 17 Python
Python守护进程实现过程详解
Feb 10 Python
pycharm永久激活超详细教程
Oct 29 Python
解决pycharm下载库时出现Failed to install package的问题
Sep 04 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系统流量分析的程序
2006/10/09 PHP
PHP 各种排序算法实现代码
2009/08/20 PHP
30 个很棒的PHP开源CMS内容管理系统小结
2011/10/14 PHP
php 不使用js实现页面跳转
2014/02/11 PHP
php初始化对象和析构函数的简单实例
2014/03/11 PHP
php中用memcached实现页面防刷新功能
2014/08/19 PHP
PHP+iFrame实现页面无需刷新的异步文件上传
2014/09/16 PHP
PHP实现绘制二叉树图形显示功能详解【包括二叉搜索树、平衡树及红黑树】
2017/11/16 PHP
另一个javascript小测验(代码集合)
2011/07/27 Javascript
JavaScript中消除闭包的一般方法介绍
2015/03/16 Javascript
js下拉选择框与输入框联动实现添加选中值到输入框的方法
2015/08/17 Javascript
jQuery EasyUI常用数据验证汇总
2016/09/18 Javascript
vuejs在解析时出现闪烁的原因及防止闪烁的方法
2016/09/19 Javascript
简单的js计算器实现
2016/10/26 Javascript
Jquery 整理元素选取、常用方法一览表
2016/11/26 Javascript
用nodejs搭建websocket服务器
2017/01/23 NodeJs
Angular.js中ng-include用法及多标签页面的实现方式详解
2017/05/07 Javascript
vue引入swiper插件的使用实例
2017/07/19 Javascript
vue axios封装及API统一管理的方法
2019/04/18 Javascript
解决layui数据表格table的横向滚动条显示问题
2019/09/04 Javascript
JS实现简单日历特效
2020/01/03 Javascript
[06:50]DSPL次级职业联赛十强晋级之路
2014/11/18 DOTA
python中元类用法实例
2014/10/10 Python
Python中列表的一些基本操作知识汇总
2015/05/20 Python
Django的数据模型访问多对多键值的方法
2015/07/21 Python
Python最小二乘法矩阵
2019/01/02 Python
阿里云ECS服务器部署django的方法
2019/08/29 Python
Python的缺点和劣势分析
2019/11/19 Python
在python中求分布函数相关的包实例
2020/04/15 Python
用HTML5制作烟火效果的教程
2015/05/12 HTML / CSS
英国网上花店:Bunches
2016/11/29 全球购物
MANGO官方网站:西班牙芒果服装品牌
2017/01/15 全球购物
俄罗斯隐形眼镜和眼镜在线商店:Cronos
2020/06/02 全球购物
介绍一下gcc特性
2015/10/31 面试题
企业宣传语大全
2015/07/13 职场文书
小学语文课《掌声》教学反思
2016/03/03 职场文书