最基础的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中用memcached来减少数据库查询次数的教程
Apr 07 Python
在Python中使用poplib模块收取邮件的教程
Apr 29 Python
python批量修改图片大小的方法
Jul 24 Python
python 实现批量xls文件转csv文件的方法
Oct 23 Python
python 构造三维全零数组的方法
Nov 12 Python
pandas数据集的端到端处理
Feb 18 Python
使用Django开发简单接口实现文章增删改查
May 09 Python
python3 pygame实现接小球游戏
May 14 Python
Django model select的多种用法详解
Jul 16 Python
Python内置异常类型全面汇总
May 28 Python
python实现一个简单RPC框架的示例
Oct 28 Python
Python Matplotlib绘制条形图的全过程
Oct 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
如何使用脚本模仿登陆过程
2006/11/22 PHP
使用php+Ajax实现唯一校验实现代码[简单应用]
2011/11/29 PHP
PHP解密Unicode及Escape加密字符串
2015/05/17 PHP
javascript入门基础之私有变量
2010/02/23 Javascript
3Z版基于jquery的图片复选框(asp.net+jquery)
2010/04/12 Javascript
js限制文本框只能输入数字方法小结
2014/06/16 Javascript
Javascript常用字符串判断函数代码分享
2014/12/08 Javascript
JavaScript实现的多种鼠标拖放效果
2015/11/03 Javascript
对jquery的ajax进行二次封装以及ajax缓存代理组件:AjaxCache详解
2016/04/11 Javascript
Bootstrap模态框禁用空白处点击关闭
2016/10/20 Javascript
使用Browserify来实现CommonJS的浏览器加载方法
2017/05/14 Javascript
[02:24]DOTA2痛苦女王 英雄基础教程
2013/11/26 DOTA
Python编程中用close()方法关闭文件的教程
2015/05/24 Python
Python中实现三目运算的方法
2015/06/21 Python
Python常用知识点汇总
2016/05/08 Python
在python中利用GDAL对tif文件进行读写的方法
2018/11/29 Python
不到20行代码用Python做一个智能聊天机器人
2019/04/19 Python
对PyQt5中树结构的实现方法详解
2019/06/17 Python
PyQt5通信机制 信号与槽详解
2019/08/07 Python
python2使用bs4爬取腾讯社招过程解析
2019/08/14 Python
Python3常见函数range()用法详解
2019/12/30 Python
浅谈CSS3中display属性的Flex布局的方法
2017/08/14 HTML / CSS
GAP美国官网:美国休闲时尚品牌
2016/08/26 全球购物
意大利辅助药品、药物和补品在线销售:FarmaEurope
2020/04/29 全球购物
SQL面试题
2013/04/30 面试题
当x.equals(y)等于true时,x.hashCode()与y.hashCode()可以不相等,这句话对不对
2015/05/02 面试题
工业设计专业推荐信
2013/10/29 职场文书
大学生入党自我鉴定
2013/10/31 职场文书
军训鉴定表自我鉴定
2014/02/13 职场文书
群众路线党课主持词
2014/04/01 职场文书
初中教师个人总结
2015/02/10 职场文书
舞出我人生观后感
2015/06/16 职场文书
公司规章制度范本
2015/08/03 职场文书
大学体育课感想
2015/08/10 职场文书
vue.js 使用原生js实现轮播图
2022/04/26 Vue.js
MySQL示例讲解数据库约束以及表的设计
2022/06/16 MySQL