最基础的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中字典的基本知识初步介绍
May 21 Python
Python 的内置字符串方法小结
Mar 15 Python
python爬取51job中hr的邮箱
May 14 Python
python中根据字符串调用函数的实现方法
Jun 12 Python
Python爬虫设置代理IP的方法(爬虫技巧)
Mar 04 Python
Python 元类实例解析
Apr 04 Python
python实现图片筛选程序
Oct 24 Python
基于Django的乐观锁与悲观锁解决订单并发问题详解
Jul 31 Python
python实现七段数码管和倒计时效果
Nov 23 Python
python 按钮点击关闭窗口的实现
Mar 04 Python
python录音并调用百度语音识别接口的示例
Dec 01 Python
Django cookie和session的应用场景及如何使用
Apr 29 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
用windows下编译过的eAccelerator for PHP 5.1.6实现php加速的使用方法
2007/09/30 PHP
php 对输入信息的进行安全过滤的函数代码
2012/06/29 PHP
php使用qr生成二维码的示例分享
2014/01/20 PHP
PHP面试题之文件目录操作
2015/10/15 PHP
微信公众号判断用户是否已关注php代码解析
2016/06/24 PHP
Yii核心验证器api详解
2016/11/23 PHP
laravel框架路由分组,中间件,命名空间,子域名,路由前缀实例分析
2020/02/18 PHP
js+CSS 图片等比缩小并垂直居中实现代码
2008/12/01 Javascript
JS匀速运动演示示例代码
2013/11/26 Javascript
11种ASP连接数据库的方法
2015/09/18 Javascript
jQuery动态加载css文件实现方法
2016/06/15 Javascript
Bootstrap幻灯片轮播图支持触屏左右手势滑动的实现方法
2016/10/13 Javascript
Vue 仿百度搜索功能实现代码
2017/02/16 Javascript
js实现登录框鼠标拖拽效果
2017/03/09 Javascript
JS获取指定月份的天数两种实现方法
2018/06/22 Javascript
微信小程序滑动选择器的实现代码
2018/08/10 Javascript
bootstrap中的导航条实例代码详解
2019/05/20 Javascript
vue-form表单验证是否为空值的实例详解
2019/10/29 Javascript
详解JavaScript中精度失准问题及解决方法
2020/02/04 Javascript
vue 组件间的通信之子组件向父组件传值的方式
2020/07/29 Javascript
vue实现PC端分辨率适配操作
2020/08/03 Javascript
vue-cli 关闭热更新操作
2020/09/18 Javascript
解决vue2中使用elementUi打包报错的问题
2020/09/22 Javascript
Javascript实现单选框效果
2020/12/09 Javascript
用Python遍历C盘dll文件的方法
2015/05/06 Python
详解Python中的strftime()方法的使用
2015/05/22 Python
python3实现随机数
2018/06/25 Python
python实现手机销售管理系统
2019/03/19 Python
Python编译为二进制so可执行文件实例
2019/12/23 Python
Pytorch GPU显存充足却显示out of memory的解决方式
2020/01/13 Python
pycharm 更改创建文件默认路径的操作
2020/02/15 Python
大学生学期个人总结
2015/02/12 职场文书
员工拾金不昧表扬稿
2015/05/05 职场文书
食堂卫生管理制度
2015/08/04 职场文书
感恩信:写给爸爸妈妈的一封感谢信
2019/09/12 职场文书
动作冒险《Hell Is Us》将采用虚幻5 消灭怪物探索王国
2022/04/13 其他游戏