最基础的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实现图片变亮或者变暗的方法
Jun 01 Python
Python实现base64编码的图片保存到本地功能示例
Jun 22 Python
python3读取excel文件只提取某些行某些列的值方法
Jul 10 Python
python使用__slots__让你的代码更加节省内存
Sep 05 Python
深入理解Django自定义信号(signals)
Oct 15 Python
解决python2 绘图title,xlabel,ylabel出现中文乱码的问题
Jan 29 Python
python实现视频分帧效果
May 31 Python
Django模型序列化返回自然主键值示例代码
Jun 12 Python
基于TensorFlow常量、序列以及随机值生成实例
Jan 04 Python
Python如何使用OS模块调用cmd
Feb 27 Python
Python 爬虫的原理
Jul 30 Python
Python常用base64 md5 aes des crc32加密解密方法汇总
Nov 06 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/23 PHP
Apache+php+mysql在windows下的安装与配置图解(最新版)
2008/11/30 PHP
phpmyadmin导入(import)文件限制的解决办法
2009/12/11 PHP
php生成xml简单实例代码
2009/12/16 PHP
PHP实现从PostgreSQL数据库检索数据分页显示及根据条件查找数据示例
2018/06/09 PHP
TP5(thinkPHP5框架)基于bootstrap实现的单图上传插件用法示例
2019/05/29 PHP
ThinkPHP框架结合Ajax实现用户名校验功能示例
2019/07/03 PHP
arguments对象
2006/11/20 Javascript
jQuery学习笔记[1] jQuery中的DOM操作
2010/12/03 Javascript
原来Jquery.load的方法可以一直load下去
2011/03/28 Javascript
使用firebug进行调试javascript的示例
2013/12/16 Javascript
js鼠标滑轮滚动事件绑定的简单实例(兼容主流浏览器)
2014/01/14 Javascript
浅谈JavaScript 框架分类
2014/11/10 Javascript
javascript仿京东导航左侧分类导航下拉菜单效果
2020/11/25 Javascript
基于BootStarp的Dailog
2016/04/28 Javascript
移动端jQuery修正Web页面滑动时div问题的两则实例
2016/05/30 Javascript
jQuery弹出窗口简单实现代码
2017/03/09 Javascript
vue-cli 自定义指令directive 添加验证滑块示例
2017/10/19 Javascript
微信小程序实现通过双向滑动缩放图片大小的方法
2018/12/30 Javascript
JS+css3实现幻灯片轮播图
2020/08/14 Javascript
python实现批量获取指定文件夹下的所有文件的厂商信息
2014/09/28 Python
Python常用的爬虫技巧总结
2016/03/28 Python
Python3.x对JSON的一些操作示例
2017/09/01 Python
python多线程扫描端口(线程池)
2019/09/04 Python
浅析Python 责任链设计模式
2020/09/11 Python
菲律宾最大的网上花店和礼品店:PhilFlower.com
2018/02/09 全球购物
丝芙兰波兰:Sephora.pl
2018/03/25 全球购物
怎样比较两个类型为String的字符串
2016/08/17 面试题
EJB3.1都有哪些改进
2012/11/17 面试题
应届生骨科医生求职信
2013/10/31 职场文书
幼儿园教师工作感言
2014/02/15 职场文书
大学生社会实践评语
2014/04/25 职场文书
小学校长汇报材料
2014/08/20 职场文书
2014年医德医风工作总结
2014/11/13 职场文书
离婚答辩状范文
2015/05/22 职场文书
地道战观后感500字
2015/06/04 职场文书