设为首页 收藏本站
查看: 508|回复: 0

[经验分享] Python Socket Programming

[复制链接]

尚未签到

发表于 2015-11-29 11:48:41 | 显示全部楼层 |阅读模式
  本文介绍使用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 "", line 1, in
  
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。

服务端
  服务端程序执行的步骤:


  • 创建服务端socket  

  • 将服务端socket绑定到指定的地址和端口  

  • 监听连接  

  • 接受客户端连接  

  • 处理客户端的数据  

  • 关闭客户端连接
  一个简单的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)
  

参考资料


  • Socket Programming HOWTO  

  • Porting Python 2 Code to Python 3

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-144886-1-1.html 上篇帖子: Python开发入门与实战4-模板页面 下篇帖子: python学习之--自定义函数:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表