最基础的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入门篇之字符串
Oct 17 Python
Python发送email的3种方法
Apr 28 Python
使用python在本地电脑上快速处理数据
Jun 22 Python
Python基于Flask框架配置依赖包信息的项目迁移部署
Mar 02 Python
详解Python给照片换底色(蓝底换红底)
Mar 22 Python
详解用python写网络爬虫-爬取新浪微博评论
May 10 Python
对Python3之方法的覆盖与super函数详解
Jun 26 Python
python文字转语音实现过程解析
Nov 12 Python
python opencv实现信用卡的数字识别
Jan 12 Python
Python 保存加载mat格式文件的示例代码
Aug 04 Python
Python爬虫之Selenium下拉框处理的实现
Dec 04 Python
浅谈Selenium+Webdriver 常用的元素定位方式
Jan 13 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多图上传小程序代码
2011/07/17 PHP
php获取目标函数执行时间示例
2014/03/04 PHP
php下载文件源代码(强制任意文件格式下载)
2014/05/09 PHP
PHP模板引擎Smarty内建函数foreach,foreachelse用法分析
2016/04/11 PHP
尽可能写&quot;友好&quot;的&quot;Javascript&quot;代码
2007/01/09 Javascript
JS中不为人知的五种声明Number的方式简要概述
2013/02/22 Javascript
基于Bootstrap+jQuery.validate实现Form表单验证
2014/12/16 Javascript
jquery自动补齐功能插件flexselect用法示例
2016/08/06 Javascript
基于JavaScript实现鼠标箭头移动图片跟着移动
2016/08/30 Javascript
jquery获取点击控件的绝对位置简单实例
2016/10/13 Javascript
简单实现JS计算器功能
2016/12/21 Javascript
vue中用动态组件实现选项卡切换效果
2017/03/25 Javascript
angular 基于ng-messages的表单验证实例
2017/05/04 Javascript
BootStrap 表单控件之单选按钮水平排列
2017/05/23 Javascript
简述JS控制台的使用
2018/07/15 Javascript
微信小程序实现单选功能
2018/10/30 Javascript
Vue el-autocomplete远程搜索下拉框并实现自动填充功能(推荐)
2019/10/25 Javascript
JavaScript实现省份城市的三级联动
2020/02/11 Javascript
Python中列表、字典、元组、集合数据结构整理
2014/11/20 Python
Python中的os.path路径模块中的操作方法总结
2016/07/07 Python
Python实现在线音乐播放器
2017/03/03 Python
基于python中staticmethod和classmethod的区别(详解)
2017/10/24 Python
解决nohup重定向python输出到文件不成功的问题
2018/05/11 Python
python去除文件中重复的行实例
2018/06/29 Python
对python数据切割归并算法的实例讲解
2018/12/12 Python
python3中类的继承以及self和super的区别详解
2019/06/26 Python
在Python中画图(基于Jupyter notebook的魔法函数)
2019/10/28 Python
python 字段拆分详解
2019/12/17 Python
python 爬取古诗文存入mysql数据库的方法
2020/01/08 Python
解决keras模型保存h5文件提示无此目录问题
2020/07/01 Python
python推导式的使用方法实例
2021/02/28 Python
详解前端HTML5几种存储方式的总结
2016/12/27 HTML / CSS
大学生实习介绍信
2015/05/05 职场文书
2015年学校教科室工作总结
2015/07/20 职场文书
最美劳动诗,致敬所有的劳动者!
2019/07/12 职场文书
彻底弄懂Python中的回调函数(callback)
2022/06/25 Python