最基础的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中map()与zip()操作方法
Feb 27 Python
python生成词云的实现方法(推荐)
Jun 13 Python
Python实现定时备份mysql数据库并把备份数据库邮件发送
Mar 08 Python
python3通过selenium爬虫获取到dj商品的实例代码
Apr 25 Python
python中使用while循环的实例
Aug 05 Python
使用Python脚本zabbix自定义key监控oracle连接状态
Aug 28 Python
PHP统计代码行数的小代码
Sep 19 Python
详解python中eval函数的作用
Oct 22 Python
python 读取更新中的log 或其它文本方式
Dec 24 Python
python实现单目标、多目标、多尺度、自定义特征的KCF跟踪算法(实例代码)
Jan 08 Python
Python classmethod装饰器原理及用法解析
Oct 17 Python
python自动化发送邮件实例讲解
Jan 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创建PDF中文文档
2006/10/09 PHP
十天学会php之第十天
2006/10/09 PHP
php扩展ZF――Validate扩展
2008/01/10 PHP
PHP中冒号、endif、endwhile、endfor使用介绍
2010/04/28 PHP
PHP 冒泡排序算法的实现代码
2010/08/08 PHP
解析linux下安装memcacheq(mcq)全过程笔记
2013/06/27 PHP
php验证session无效的解决方法
2014/11/04 PHP
php简单实现数组分页的方法
2016/04/30 PHP
背景音乐每次刷新都可以自动更换
2007/02/01 Javascript
JavaScript类和继承 constructor属性
2010/03/04 Javascript
JS调用CS里的带参方法实例
2013/08/01 Javascript
js利用数组length属性清空和截短数组的小例子
2014/01/15 Javascript
jscript读写二进制文件的方法
2015/04/22 Javascript
JS+CSS实现的漂亮渐变背景特效代码(6个渐变效果)
2016/03/25 Javascript
Vue.JS实现垂直方向展开、收缩不定高度模块的JS组件
2018/06/19 Javascript
vue项目创建并引入饿了么elementUI组件的步骤
2019/04/11 Javascript
Node.js中Koa2在控制台输出请求日志的方法示例
2019/05/02 Javascript
详解js location.href和window.open的几种用法和区别
2019/12/02 Javascript
微信小程序登录时如何获取input框中的内容
2019/12/04 Javascript
vue+element 实现商城主题开发的示例代码
2020/03/26 Javascript
[03:49]2016完美“圣”典风云人物:AMS专访
2016/12/06 DOTA
python插入数据到列表的方法
2015/04/30 Python
Python时间模块datetime、time、calendar的使用方法
2016/01/13 Python
python 简单的多线程链接实现代码
2016/08/28 Python
python中的break、continue、exit()、pass全面解析
2017/08/05 Python
Python爬虫爬取一个网页上的图片地址实例代码
2018/01/16 Python
在python2.7中用numpy.reshape 对图像进行切割的方法
2018/12/05 Python
PyCharm2018 安装及破解方法实现步骤
2019/09/09 Python
Python中__repr__和__str__区别详解
2019/11/07 Python
python 基于PYMYSQL使用MYSQL数据库
2020/12/24 Python
纯CSS3+DIV实现小三角形边框效果的示例代码
2020/08/03 HTML / CSS
html5 div布局与table布局详解
2016/11/16 HTML / CSS
青年教师典范事迹材料
2014/01/31 职场文书
幼儿园个人师德总结
2015/02/06 职场文书
MySQL远程无法连接的一些常见原因总结
2022/09/23 MySQL
解决ubuntu安装软件时,status-code=409报错的问题
2022/12/24 Servers