最基础的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连接池实现示例程序
Nov 26 Python
python中__call__方法示例分析
Oct 11 Python
在类Unix系统上开始Python3编程入门
Aug 20 Python
Python 2与Python 3版本和编码的对比
Feb 14 Python
使用Python写CUDA程序的方法
Mar 27 Python
pycharm重置设置,恢复默认设置的方法
Oct 22 Python
django-rest-swagger的优化使用方法
Aug 29 Python
详解Python3 pickle模块用法
Sep 16 Python
Python中SQLite如何使用
May 27 Python
Python使用paramiko连接远程服务器执行Shell命令的实现
Mar 04 Python
如何在向量化NumPy数组上进行移动窗口
May 18 Python
端午节将至,用Python爬取粽子数据并可视化,看看网友喜欢哪种粽子吧!
Jun 11 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字符转义相关函数小结(php下的转义字符串)
2007/04/12 PHP
php源码的使用方法讲解
2019/09/26 PHP
在ASP.NET中使用JavaScript脚本的方法
2013/11/12 Javascript
javascript实现动态侧边栏代码
2014/02/19 Javascript
从零学jquery之如何使用回调函数
2014/05/16 Javascript
JavaScript Math.floor方法(对数值向下取整)
2015/01/09 Javascript
JS判断客服QQ号在线还是离线状态的方法
2015/01/13 Javascript
js实现宇宙星空背景效果的方法
2015/03/03 Javascript
如何用jQuery实现ASP.NET GridView折叠伸展效果
2015/09/26 Javascript
jquery easyui datagrid实现增加,修改,删除方法总结
2016/05/25 Javascript
精彩的Bootstrap案例分享 重点在注释!(选项卡、栅格布局)
2016/07/01 Javascript
jquery  实现轮播图详解及实例代码
2016/10/12 Javascript
分享vue.js devtools遇到一系列问题
2017/10/24 Javascript
vue-router 源码之实现一个简单的 vue-router
2018/07/02 Javascript
layui实现三级联动效果
2019/07/26 Javascript
ES6 新增的创建数组的方法(小结)
2019/08/01 Javascript
在layui中layer弹出层点击事件无效的解决方法
2019/09/05 Javascript
Vue自定义组件的四种方式示例详解
2020/02/28 Javascript
微信小程序实现单个或多个倒计时功能
2020/11/01 Javascript
Python中的True,False条件判断实例分析
2015/01/12 Python
一篇文章入门Python生态系统(Python新手入门指导)
2015/12/11 Python
深入解析Python中的__builtins__内建对象
2016/06/21 Python
Python标准库sched模块使用指南
2017/07/06 Python
使用python采集脚本之家电子书资源并自动下载到本地的实例脚本
2018/10/23 Python
Python Django的安装配置教程图文详解
2019/07/17 Python
python 实现线程之间的通信示例
2020/02/14 Python
python dir函数快速掌握用法技巧
2020/12/09 Python
深入理解css中vertical-align属性
2017/04/18 HTML / CSS
详解CSS3中强大的filter(滤镜)属性
2017/06/29 HTML / CSS
HTML5等待加载动画效果
2017/07/27 HTML / CSS
html5 viewport使用方法示例详解
2013/12/02 HTML / CSS
违反工作纪律检讨书
2014/02/15 职场文书
优秀学生干部先进事迹材料
2014/05/26 职场文书
党支部培养考察意见
2015/06/02 职场文书
2019经典广告词集锦!
2019/07/02 职场文书
基于PyTorch实现一个简单的CNN图像分类器
2021/05/29 Python