Python socket 通信
2016-07-12 19:10
375 查看
最近在做论文实验,涉及到有关于socket通信的内容,在此做一个总结。
关于Socket的基本内容,我是看了这篇博客,来自于点击打开链接,里面涉及到了有关Python 中socket通信的基本知识。下面介绍一下基于TCP的socket通信基本代码
Server
#server import socket import pickle #python 的序列化模块 local=('127.0.0.1', 5000) #绑定的地址和端口号 server=socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(local) server.listen(1) conn,addr=server.accept() data=pickle.loads(conn.recv(1024)) conn.close()Client
#Client import socket import pickle addr=('127.0.0.1',5000) client=socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(addr) data="hello world" client.sendall(pickle.dumps(data)) #python3 总sendall()只能发送字节数据,需要通过pickle模块序列化数据 client.close()上面可以实现简单的socket模块的通信,利用pickle模块我们可以实现发送list,tuple等数据,只需要pickle.dumps(list)后发送数据。
下面说一下子啊具体实验过程中遇到的一些问题,以及自己网上搜到的一些解决方法。
主要的问题是
client.sendall(pickle.dumps(data))
<pre name="code" class="python">data=pickle.loads(conn.recv(1024))
在运行时server端会报如下错误:
ran out of input
主要原因是发送的data数据量太大导致了server端无法完全接受,
conn.recv(1024)
接受的最大字节数为1024,如果数据量不是太大,可以改为
conn.recv(1024*10)即可解决报错的问题。不过我试了一下太大的数据这样做不行,我有次改为
conn.recv(1024*10000)发送还是会报错,证明这不是一个好方法。
然后想到的方法是将大量数据线保存成文件,在发送文件到Server端,解析出数据,代码如下
#server import socket import pickle #python 的序列化模块 local=('127.0.0.1', 5000) #绑定的地址和端口号 server=socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(local) server.listen(1) conn,addr=server.accept() f=open('data','wb') #以wb模式打开data文件,wb代表以字节形式写入文件
while True:
<span style="white-space:pre"> </span>message=conn.recv(1024)
<span style="white-space:pre"> </span>if not message:
<span style="white-space:pre"> </span>break
<span style="white-space:pre"> </span>f.write(message)
f.close()
f=open('data','rb')
data=pickle.load(f) #pickle 的load()函数从一个具有read()或readline()方法的对象中恢复数据
f.close()
conn.close()
#Client import socket import pickle addr=('127.0.0.1',5000) client=socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(addr) f=open('message','wb') pickle.dump(message,f) f.close() f=open('message','rb') while 1: data=f.read(1024) if not data: break s.send(data) f.close() client.close() client.close()
后来在网上搜索发现了另一种简单的方法,如果事先知道要传输的数据的大小,可以将其长度加在发送的数据前面,发送过去,具体如下:
#server import socket import struct import pickle Host='127.0.0.1' port=5007 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.bind((Host,port)) s.listen(1) coon,addr=s.accept() buff=b'' buff=coon.recv(2) #这里2 是Client端中length的长度大小 length=struct.unpack('!H',buff)[0] data=pickle.loads(coon.recv(length)) print(data) coon.close()
#client import socket import struct import pickle Host='127.0.0.1' port=5007 data="hello world" s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect((Host,port)) packet=pickle.dumps(data) length=struct.pack('!H',len(packet)) s.sendall(length) s.sendall(packet) s.close()最后发现了另一种最简便的方法:利用multiprocessing.connection 模块的Client和Listener,可以不将数据序列化传输,并且不用指定数据的大小,具体代码如下:
#server from multiprocessing.connection import Listener Host='127.0.0.1' port=5007 server=Listener((Host,port)) conn=server.accept() data=conn.recv() conn.close()
#client from multiprocessing.connection import Client Host='127.0.0.1' port=5007 data="hello world" client=Client((Host,port)) client.send(data) client.close()
相关文章推荐
- "Python"学习笔记----函数式编程
- 在Python中通过threading模块定义和调用线程的方法
- 举例讲解Python编程中对线程锁的使用
- Python Opearte MS-SQL Use Pymssql
- 使用Python编写一个最基础的代码解释器的要点解析
- Python 小甲鱼教程 课后练习20
- python 里的深复制 和浅复制概念
- 用python自建一个DNS服务器
- Python中使用bidict模块双向字典结构的奇技淫巧
- ubuntu下PIL安装
- Python基础知识补充(重要)-作用域、特殊语法
- Python使用SocketServer模块编写基本服务器程序的教程
- Python基础教程笔记 第二章
- Python运算符
- Python行与缩进
- Python对象简介
- Python 数据类型
- Python是一门杰出的语言,值得你去学习
- Elasticsearch集群搭建及Python交互
- 零基础学习Python