实际上,我试图将经过训练的数据从系统1发送到系统2,这样我就可以在系统2中进行KNN分类。但是我发现很难发送经过训练的数据,因为它非常大。有没有办法通过套接字将大量数据从一个系统发送到另一个系统。在
系统1
import sys
import time
import pickle
from sklearn.datasets import load_files
from sklearn.neighbors import KNeighborsClassifier
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from socket import socket, gethostbyname, AF_INET, SOCK_DGRAM
PORT_NUMBER = 5000
hostName = gethostbyname('0.0.0.0')
mySocket = socket( AF_INET, SOCK_DGRAM )
mySocket.bind( (hostName, PORT_NUMBER) )
print ("Test server listening on port {0}".format(PORT_NUMBER))
(data,addr) = mySocket.recvfrom(15)
print data
mySocket.sendto("Connected...", addr)
(data,addr) = mySocket.recvfrom(20000000)
msg=pickle.loads(data)
twenty_train=msg
mySocket.sendto("one", addr)
(data,addr) = mySocket.recvfrom(300000000)
ms=pickle.loads(data)
X_train_tfidf=ms
knn=KNeighborsClassifier(n_neighbors=3)
clf = knn.fit(X_train_tfidf, twenty_train)
f=open(sys.argv[1],'r')
g=f.read()
ans = g.strip('\n')
if ans.endswith(' '):
ans = ans.rstrip(' ')
docs_new = [ans]
mySocket.sendto(ans, addr)
(data,addr) = mySocket.recvfrom(1000000)
msg2=pickle.loads(data)
X_new_tfidf=msg2
mySocket.sendto("two", addr)
predicted = clf.predict(X_new_tfidf)
(data,addr) = mySocket.recvfrom(100000)
msg3=pickle.loads(data)
names = msg3
for doc, category in zip(docs_new, predicted):
print('%r => %s' % (doc, names[category]))
sys.exit()
系统2
^{pr2}$错误
Traceback (most recent call last):
File "cl.py", line 43, in <module>
sock.sendto(pickle.dumps(X_train_tfidf),addr)
socket.error: [Errno 90] Message too long
是的。您应该使用
SOCK_STREAM
(TCP)套接字来发送大数据。使用SOCK_DGRAM
(UDP)意味着每条消息都是独立的,并且必须符合UDP数据报的最大大小(小于64K)。如果您使用TCP会话,则可以传输的大小没有限制。在但是,由于TCP不维护消息边界,因此需要对单个消息进行帧处理。这通常是通过在消息前面发送某种报头来完成的,以便接收方在解码之前知道要读取多少。在您的例子中,您需要确保在调用
pickle.loads
之前收到一个完整的数据块。报头可以简单到一个包含剩余消息长度的32位整数。(最好把它放在二进制中,这样你就知道它有多大。您可以使用struct
模块的pack
和unpack
来实现这一点另一种方法是简单地为每个要发送的数据块创建一个全新的连接:即连接、发送所有数据、关闭。这样,接收器可以一直接收,直到它得到一个EOF,此时它知道它拥有整个数据块。在
相关问题 更多 >
编程相关推荐